Redis深入之内存回收和对象共享

内存回收

C语言并不具备自动内存回收功能,Redis在自己的对象系统中构建了一个引用计数技术实现的内存回收机制,通过这一机制,程序可以通过跟踪对象的引用计数信息,在适当的时候自动释放对象并进行内存回收。每个对象的引用计数信息由redis对象结构的refcount属性记录,创建一个新对象时,引用计数值会初始化为1;对象被一个新程序使用时,它的引用计数值会被增1;不再被一个程序使用时,减1;引用计数值变为0,对象所占用的内存会被释放。

对象共享

对象的引用计数属性还带有对象共享的作用。Redis会共享值为0到9999的字符串对象。如果键A创建了一个包含整数值100的字符串对象作为值对象,键B也要创建一个同样保存了整数值100的字符串对象作为值对象,服务器可以让键A和键B共享同一个字符串对象,Redis中需要两步,1)将数据库键的值指针指向一个现有的值对象;2)将被共享的值对象的引用计数增一。共享对象机制对于节约内存非常有帮助,数据库中保存的相同值对象越多,对象共享机制就能节约越多的内存。

问:Redis为什么只对包含整数值得字符串对象进行共享?

当服务器考虑将一个共享对象设置为键的值对象时,程序需要先检查给定的共享对象和键想创建的目标对象是否完全相同。一个共享对象保存的值越复杂,验证共享对象和目标对象是否相同所需的复杂度就会越高,消耗的CPU时间也会越多。

如果共享对象是保存整数值的字符串对象,验证操作的复杂度O(1)

如果共享对象是保存字符串值的字符串对象,验证操作的复杂度O(N)

如果共享对象是包含多个值(比如列表对象或者哈希对象)对象,验证操作的复杂度O(N2

故尽管共享更复杂的对象可以节约更多的内存,但受到CPU时间的限制,Redis只对包含整数值得字符串对象进行共享。

时间: 2024-11-08 17:09:19

Redis深入之内存回收和对象共享的相关文章

第三章 JVM内存回收区域+对象存活的判断+引用类型+垃圾回收线程

注意:本文主要参考自<深入理解Java虚拟机(第二版)> 说明:查看本文之前,推荐先知道JVM内存结构,见<第一章 JVM内存结构> 1.内存回收的区域 堆:这是GC的主要区域 方法区:回收两样东西 无用的类 废弃的常量 栈和PC寄存器是线程私有区域,不发生GC 2.怎样判断对象是否存活 垃圾回收:回收掉死亡对象所占的内存.判断对象是否死亡,有两种方式: 引用计数法 原理:给对象添加一个引用计数器,每当有一个地方引用它时,计数器值+1:引用失效时,计数器值-1 实际中不用,不用的两

redis 系列15 数据对象的(类型检查,内存回收,对象共享)和数据库切换

原文:redis 系列15 数据对象的(类型检查,内存回收,对象共享)和数据库切换 一.  概述 对于前面的五章中,已清楚了数据对象的类型以及命令实现,其实还有一种数据对象为HyperLogLog,以后需要用到再了解.下面再了解类型检查,内存回收,对象共享,对象的空转时长. 1.1   类型检查与命令多态 redis中用于操作键的命令基本上可以分为两种类型,一种是可以对任何的键执行,如:del, expire,rename,type,object 这些命令等,对于这些命令属于多态命令.另一种命令

[java,2017-05-15] 内存回收 (流程、时间、对象、相关算法)

内存回收的流程 java的垃圾回收分为三个区域新生代.老年代. 永久代 一个对象实例化时 先去看伊甸园有没有足够的空间:如果有 不进行垃圾回收 ,对象直接在伊甸园存储:如果伊甸园内存已满,会进行一次minor gc:然后再进行判断伊甸园中的内存是否足够:如果不足 则去看存活区的内存是否足够:如果内存足够,把伊甸园部分活跃对象保存在存活区,然后把对象保存在伊甸园:如果内存不足,向老年代发送请求,查询老年代的内存是否足够:如果老年代内存足够,将部分存活区的活跃对象存入老年代.然后把伊甸园的活跃对象放

redis 如何做内存优化?

edis所有的数据都在内存中,而内存又是非常宝贵的资源.对于如何优化内存使用一直是Redis用户非常关注的问题.本文让我们深入到Redis细节中,学习内存优化的技巧.分为如下几个部分: 一.redisObject对象 二.缩减键值对象 三.共享对象池 四.字符串优化 五.编码优化 六.控制key的数量 一. redisObject对象 Redis存储的所有值对象在内部定义为redisObject结构体,内部结构如下图所示. Redis存储的数据都使用redisObject来封装,包括string

Redis额内存回收策略和内存上限

内存上限Redis可以通过 maxmemory 参数来限制最大可用内存,主要为了避免Redis内存超过操作系统内存,从而导致服务器响应变慢甚至死机的情况. maxmemory 参数限制的是Redis的对象内存大小,也就是 used_memory 对应的内存大小.由于内存碎片的存在,所以Redis服务器实际占用的内存是要超过 maxmemory 的. 所以我们在设置Redis内存上限的时候要预留一部分内存出来,比如说一台32GB内存的机器,可以启动 3 台8GB内存的Redis,预留8GB给机器其

Redis 系列(04-2)Redis原理 - 内存回收

目录 Redis 系列(04-2)Redis原理 - 内存回收 Redis 系列目录 1. 过期策略 1.1 定时过期(主动淘汰) 1.2 惰性过期(被动淘汰) 1.3 定期过期 2. 淘汰策略 2.1 最大内存设置 2.2 淘汰策略 2.4 LFU Redis 系列(04-2)Redis原理 - 内存回收 Redis 系列目录 相关文档推荐: Redis - LRU Reids 所有的数据都是存储在内存中的,在某些情况下需要对占用的内存空间进行回收.内存回收主要分为两类,一类是 key 过期,

JVM自动内存管理:对象判定和回收算法

可回收对象的判断方法 1.引用计数算法 2.可达性分析算法 引用计数算法 给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1:当引用失效时,计数器值就减1:任何时刻计数器为0的对象就是不可能再被使用的. 引用计数算法的缺陷:循环引用 可达性分析算法 可达性分析算法基本原理: 通过一些列的称为"GC Roots"的对象作为起始点,从这些节点开始进行向下搜索,搜索 所走过的路径成为引用链(Reference Chain),当一个对象到GC Roots没有任何引用连(用图论的

python cookbook第三版学习笔记十三:类和对象(五)代理类以及内存回收

代理类: 代理类的作用其实有继承有些类似,如果你想将某个实例的属性访问代理到内部另外一个实例中去,可以用继承也可以用代理.来看下代理的应用: class A:     def spam(self,x):         print 'in Class A x=%d' % x     def foo(self):         print 'in Class A:foo()' class B1:     def __init__(self):         self._a=A()       

面试官:Redis 数据库内存数据满了,会宕机吗?有内存回收?

Redis 数据库内存数据满了,会宕机吗?答案是:不会让他出现存满的情况,在使用Redis的时候我们要配置Redis能使用的最大的内存大小,存到一定容量的时候还有Redis的内存淘汰策略呢,还有LRU算法进行淘汰,等等...接下来就跟着作者一起探讨,Redis的内存淘汰策略. Redis占用内存大小 我们知道Redis是基于内存的key-value数据库,因为系统的内存大小有限,所以我们在使用Redis的时候可以配置Redis能使用的最大的内存大小. 1.通过配置文件配置 通过在Redis安装目