《垃圾回收的算法与实现》——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 ...
随机推荐
- 一次简单完整的自动化登录测试-基于python+selenium进行cnblog的自动化登录测试
Web登录测试是很常见的测试,手动测试大家再熟悉不过了,那如何进行自动化登录测试呢!本文就基于python+selenium结合unittest单元测试框架来进行一次简单但比较完整的cnblog自动化 ...
- MFC OnOk(),OnCancel(),OnClose(),OnDestroy()的区别总结
MFC OnOk(),OnCancel(),OnClose(),OnDestroy()的区别总结(转) 第一,OnOK()和OnCancel()是CDialog基类的成员函数,而OnClose()和O ...
- REST格式
首先要明确一点:REST 实际上只是一种设计风格,它并不是标准.(所以你可以看到网上一大堆的各种最佳实践,设计指南,但是没有人说设计标准).aisuhua/restful-api-design-ref ...
- VS2012 中不能安装ARCGIS 10.0 SDK的解决方法
问题描述 在ARCGIS 安装SDK时 就会出错 原因是ARCGIS SDK 10.0只能在VS2010中安装,因为我本机是安的VS2012所以安装不成功. 解决方法 一,在注册表中HKE ...
- StructuredStream StateStore机制
ref: https://jaceklaskowski.gitbooks.io/spark-structured-streaming/ StruncturedStream的statefule实现基于S ...
- C# RS232串口使用
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using Sy ...
- NetCore入门篇:(三)Net Core项目Nuget及Bower包管理
一.创建项目 1.如何创建项目,参照上一篇文章 二.程序包介绍 1.Net Core的程序包分前后端两种,后端用nuget,前端用bower. 2.与Net 不同,Net Core引用nuget包时, ...
- day 23 面向对象的命名空间与组合
创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类的属性 而类有两种属性:静态属性和动态属性 1. 静态属性就是直接在类中定义的变量 2.动态属性就是定义在类中的方法. 其 ...
- H - The LCIS on the Tree HDU - 4718
The LCIS on the Tree Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Oth ...
- Android---------------Service的学习
一.创建与启动Servcie的三个步骤 : 1. 创建一个类并继承Servcie 2.在配置文件中注册服务 3.通过Intent来启动服务 二.Service的两种启动方式 1.startServce ...