Redis内存回收算法
< 返回列表时间: 2020-03-26来源:OSCHINA
Redis使用的内存回收算法是 引用计数算法 和 LRU算法 。
1.引用计数算法: 对于创建的每一个对象都有一个与之关联的计数器,这个计数器记录着该对象被使用的次数,垃圾收集器在进行垃圾回收时,对扫描到的每一个对象判断一下计数器是否等于0,若等于0,就会释放该对象占用的内存空间,同时将该对象引用的其他对象的计数器进行减一操作。
算法实现方式: 引用计数算法的垃圾收集一般有侵入式与非侵入式两种,侵入式的实现就是将引用计数器直接根植在对象内部,用C++的思想进行解释就是,在对象的构造或者拷贝构造中进行加一操作,在对象的析构中进行减一操作;非侵入式思想就是有一块单独的内存区域,用作引用计数器。
算法优点 : 使用引用计数器,内存回收可以穿插在程序的运行中,在程序运行中,当发现某一对象的引用计数器为0时,可以立即对该对象所占用的内存空间进行回收,这种方式可以避免FULL GC(完全垃圾收集)时带来的程序暂停,Redis中就是在引用计数器为0时,对内存进行了回收。
算法缺点: 采用引用计数器进行垃圾回收,最大的缺点就是不能解决循环引用的问题,例如一个父对象持有一个子对象的引用,子对象也持有父对象的引用,这种情况下,父子对象将一直存在于JVM的堆中,无法进行回收。
2.LRU算法 : LRU是Least Recently Used的缩写,即最近最少使用,是一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰。该算法赋予每个页面一个访问字段,用来记录该页面自上次被访问以来所经历的时间 t,当必须淘汰一个页面时,选择现有页面中其 t 值最大的,即最近最少使用的页面给予淘汰。 LRU算法最为经典的实现,就是 HashMap+Double LinkedList , 时间复杂度为 O(1) ,但是 如果按照HashMap和双向链表实现,需要额外的存储存放next和prev指针,牺牲比较大的存储空间,显然是不划算的。 所以Redis中的LRU算法 ,就是随机取出若干个key,然后按照访问时间排序后,淘汰掉最不经常使用的那个。
参考文档: https://my.oschina.net/u/4480939/blog/write https://www.cnblogs.com/WJ5888/p/4371647.html https://www.cnblogs.com/WJ5888/p/4359783.html
热门排行