《垃圾回收的算法与实现》——GC标记-压缩算法
基本算法
- Mark-Compact与Mark-Sweep的第一阶段均为标记活跃对象,第二阶段则不同,压缩算法则是将活跃对象逻辑上移到一起。
Lisp2算法
- 对象头中增加forwarding指针,其用法与复制算法一样。
- Lisp2的标记阶段与其他算法一样,其压缩算法则包括以下三个步骤:
- 设定forwarding指针,遍历堆根据标记的活跃对象计算出每个对象的forwarding并给其设置进去。
- 更新指针,遍历GC root将其引用修改为对应对象的forwarding,重新遍历堆将引用更新为对象的forwarding。
- 移动对象,将活动对象移动到第一步计算的forwarding的位置,移动后将forwarding设为null。
优缺点
优点
- 相对复制算法提高堆的利用率。
- 相对清除算法不会产生碎片。
缺点
- Lisp2中的压缩阶段需要遍历3次堆。
改进
Two-Finger算法
减少遍历次数
- 限制条件为必须将对象整理为大小一致
- 对象中不需要专门设forwarding字段,直接使用对象的第一个字段当forwarding。
- 其压缩步骤如下:
- 移动对象,free指针指向堆头,live指针指向堆尾。free寻找垃圾对象,live指针寻找有效对象,而后将堆尾的有效对象复制到堆头的垃圾对象上。同时在被复制堆尾对象上设置forwarding。
- 更新指针,遍历复制结束的堆,如果引用大于free则需要更新其引用为forwarding。
- 优点压缩步骤只需要遍历两次堆,且不需要给对象增加forwarding字段。
- 缺点无序的复制不一定能兼容缓存,且需要对象一样大这个很难办到(BiBOP可以使用)。
表格算法
减少遍历次数
- 原理通过间隙表格记录对象需要移动的距离以推断其引用的改变结果。
- 将连续的活跃对象向堆头移动,每个连续的对象群记录一个位置和移动距离。
- 具体步骤如下:
- 移动对象群,从堆头开始搜索连续的活跃对象,将其第一个对象的位置和需要移动的距离写入间隙表格中(间隙表格的移动有点晕我也觉得没必要那么复杂的移动,直接写到一个固定的位置就好)
- 更新指针,遍历GC root和堆中对象,找出其引用的对象位置属于那个间隙表格的记录,而后将其引用减去对应的距离。
- 优点减少了压缩的遍历次数且保留了活跃对象的相对位置。
- 缺点维护间隙表格需要比较大的代价,其次间隙表格的记录如果是乱序的话每个对象的搜索会变成一个O(N)的复杂度。
Immix GC算法
1. 堆的构成
- 堆分成一定大小(32KB)的块(block),而后再把block分成一定大小(128B)的线(line),其以line为回收单位。
- block中有以下域:
- line:数组,表示block中的线
- mark_table:数组,表示对应线的标记。FREE(线中没对象)、MARKED(标记已完成)、ALLOCATED(有对象)、CONSERVATIVE(保守标记)
- status:表示整个block的状态,FREE(页为空)、RECYCLABLE(一部分线为空)、UNAVAILABLE(没有空的线)
- hole_cnt:block中连续的大于等于1个的空line的个数
- Immix GC根据对象大小进行分类,小型对象:比线小的;中型对象:不到8KB;大型对象:大于等于8KB。Immix GC不管理大型对象。
2. 分配
- 使用cursor和limit两个指针指向RECYCLABLE block的孔的开头和结尾来采用复制算法的分配方法,当该孔空间不够时则找下一个孔。
- 通过两个指针向右移动寻找剩下的孔,如果该block无孔了则将status置为UNAVAILABLE而后从其他RECYCLABLE中寻找孔。
- 当不能在cursor和limit之间分配中型对象时,则直接在FREE block中分配线。
- 线中分配了对象后其对应的mark_table将置为ALLOCATED
- 当小型对象占用了多个线时,后续的线状态置为CONSERVATIVE。
3. 步骤
- 选定备用From块,该步需要满足一定条件才会执行,根据孔数作为碎片化测量的指标来选择From块。
- 搜索阶段,递归遍历GC root其引用的对象所在的线标记为Marked,From块中的对象复制到To块中。复制到To块不一定钥匙FREE block也可以是一个大孔。
- 清除阶段,以线为单位进行清除,mark_table标记为ALLOCATED的线直接置为FREE,MARKED的置为ALLOCATED,CONSERVATIVE的则根据前一个线的状态决定,前个线为ALLOCATED则不需要改变,为FREE则也置为FREE
4. 总结
- 优点:将堆变为block和line的管理,解决了碎片化的问题。
- 缺点:对象不是按顺序保存,缓存不兼容
《垃圾回收的算法与实现》——GC标记-压缩算法的更多相关文章
- 垃圾回收基本算法 内存管理 GC大统一理论
<垃圾收集> (豆瓣) https://book.douban.com/subject/1157908/ 第1章 简介1.1 内存分配的历史1.1.1 静态分配1.1.2 栈分配1.1.3 ...
- Java 中级 学习笔记 2 JVM GC 垃圾回收与算法
前言 在上一节的学习中,已经了解到了关于JVM 内存相关的内容,比如JVM 内存的划分,以及JDK8当中对于元空间的定义,最后就是字符串常量池等基本概念以及容易混淆的内容,我们都已经做过一次总结了.不 ...
- JVM——GC(垃圾回收)算法
一.垃圾回收的基本概念 垃圾回收(GC,Garbage Collection),指内存中不会再被使用的对象清理掉. 垃圾回收有很多种算法:如引用计数法.标记压缩法.复制算法.分代/分区的思想 二.垃圾 ...
- 《垃圾回收的算法与实现》——保守式GC
保守式GC 保守式GC指"不能识别指针和非指针的GC". 不明确的根,寄存器.调用栈.全局变量空间等属于GC root,这些GC均不能识别出是指针还是非指针. 指针的识别,在不明确 ...
- 《垃圾回收的算法与实现》——增量式垃圾回收与RC Immix算法
增量式垃圾回收 为了控制最大暂停时间,通过逐渐推进垃圾回收即垃圾回收与mutator交替执行. 三色标记算法 以标记-清除算法为例使用三色标记算法. 利用降低吞吐量来缩短最大停顿时间. 基础 将GC中 ...
- jvm入门及理解(六)——垃圾回收与算法
一.jvm垃圾回收要做的事情 哪些内存需要回收 什么时候回收 怎么回收 二.如何判断对象已经死亡,或者说确定为垃圾 引用计数法: 给对象中添加一个引用计数器,每当有一个地方引用它时,计数器的值就加1: ...
- JVM 专题十八:垃圾回收(二)垃圾回收相关算法
1. 标记阶段 1.1 引用计数算法 1.1.1 对象存活判断 在堆里存放着几乎所有的Java对象实例,在GC执行垃圾回收之前,首先需要区分出内存中哪些是存活对象,哪些是已经死亡的对象.只有被标记为己 ...
- JVM垃圾回收(二)- Minor GC vs Major GC vs Full GC
Minor GC vs Major GC vs Full GC 垃圾回收的活动会清理对内存中的不同区域,这些事件一般被称为Minor,Major以及Full GC events.本章我们会讨论这些清理 ...
- 《垃圾回收的算法与实现》——Python垃圾回收
Python垃圾回收 python采用引用计数法进行垃圾回收 Python内存分配 python在分配内存空间时,在malloc之上堆放了3个独立的分层. python内存分配时主要由arena.po ...
随机推荐
- VS 附加不上w3wp.exe
今天调用VS 附加不上w3wp.exe,其他的站点都能附加上,就有一个站附加不上,找了各种可能都没有解决,结果发现是版本被编译成release了,原来的配置都是debug的,不知道被谁给改成relea ...
- (最小生成树) Borg Maze -- POJ -- 3026
链接: http://poj.org/problem?id=3026 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=82831#probl ...
- pytest 简介与安装
前面我们已经基本上掌握了unittest测试框架,下面我们将学习新的pytest测试框架.之于原因嘛,太流行啦!掌握一个框架是不够的,急需另外一个,于是瞅上了pytest. pytest是什么? py ...
- 洛谷P3567[POI2014]KUR-Couriers(主席树+二分)
题意:给一个数列,每次询问一个区间内有没有一个数出现次数超过一半 题解: 最近比赛太多,都没时间切水题了,刚好日推了道主席树裸题,就写了一下 然后 WA80 WA80 WA0 WA90 WA80 ?? ...
- mysql的sql性能分析器
MySQL 的SQL性能分析器主要用途是显示SQL执行的整个过程中各项资源的使用情况.分析器可以更好的展示出不良SQL的性能问题所在. mysql sql profile的使用方法 1.开启mysql ...
- Internal Server Error - http code 500
Eror Example 1 :
- ASP.NET MVC ScriptBundle 不能加载.min.js文件
比如我用 bundles.Add(new ScriptBundle("~/bundles/easyui").Include( "~/Content/easyui/jque ...
- 关于C_Sharp集中处理异常
1.写在前面 “异常意味着什么?”,想必不用对此做多余的解释,我们有理由相信在任何情况下任何应用程序都有可能出现异常,若在程序中没有对异常进行处理,则操作系统会以粗暴的方式处理掉它(弹出错误提示框), ...
- AbpZero的Swagger汉化之旅
做汉化主要是为了出一份前后端都能看得懂的在线文档,废话不多说,我们开始准备, 我们要在启动项目的Startup.cs中重定向一下swagger的读取方式 1.在这个类下面,新增一个方法: public ...
- Systemd 服务管理器
博文链接:http://www.cnblogs.com/zhenghongxin/p/8672199.html 项目中遇到有些脚本需要通过后台进程运行,保证不被异常中断,变成守护进程的第一步,就是把它 ...