基本算法

  • Mark-Compact与Mark-Sweep的第一阶段均为标记活跃对象,第二阶段则不同,压缩算法则是将活跃对象逻辑上移到一起。

Lisp2算法

  • 对象头中增加forwarding指针,其用法与复制算法一样。
  • Lisp2的标记阶段与其他算法一样,其压缩算法则包括以下三个步骤:
    • 设定forwarding指针,遍历堆根据标记的活跃对象计算出每个对象的forwarding并给其设置进去。
    • 更新指针,遍历GC root将其引用修改为对应对象的forwarding,重新遍历堆将引用更新为对象的forwarding。
    • 移动对象,将活动对象移动到第一步计算的forwarding的位置,移动后将forwarding设为null。

优缺点

优点

  1. 相对复制算法提高堆的利用率。
  2. 相对清除算法不会产生碎片。

缺点

  1. 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标记-压缩算法的更多相关文章

  1. 垃圾回收基本算法 内存管理 GC大统一理论

    <垃圾收集> (豆瓣) https://book.douban.com/subject/1157908/ 第1章 简介1.1 内存分配的历史1.1.1 静态分配1.1.2 栈分配1.1.3 ...

  2. Java 中级 学习笔记 2 JVM GC 垃圾回收与算法

    前言 在上一节的学习中,已经了解到了关于JVM 内存相关的内容,比如JVM 内存的划分,以及JDK8当中对于元空间的定义,最后就是字符串常量池等基本概念以及容易混淆的内容,我们都已经做过一次总结了.不 ...

  3. JVM——GC(垃圾回收)算法

    一.垃圾回收的基本概念 垃圾回收(GC,Garbage Collection),指内存中不会再被使用的对象清理掉. 垃圾回收有很多种算法:如引用计数法.标记压缩法.复制算法.分代/分区的思想 二.垃圾 ...

  4. 《垃圾回收的算法与实现》——保守式GC

    保守式GC 保守式GC指"不能识别指针和非指针的GC". 不明确的根,寄存器.调用栈.全局变量空间等属于GC root,这些GC均不能识别出是指针还是非指针. 指针的识别,在不明确 ...

  5. 《垃圾回收的算法与实现》——增量式垃圾回收与RC Immix算法

    增量式垃圾回收 为了控制最大暂停时间,通过逐渐推进垃圾回收即垃圾回收与mutator交替执行. 三色标记算法 以标记-清除算法为例使用三色标记算法. 利用降低吞吐量来缩短最大停顿时间. 基础 将GC中 ...

  6. jvm入门及理解(六)——垃圾回收与算法

    一.jvm垃圾回收要做的事情 哪些内存需要回收 什么时候回收 怎么回收 二.如何判断对象已经死亡,或者说确定为垃圾 引用计数法: 给对象中添加一个引用计数器,每当有一个地方引用它时,计数器的值就加1: ...

  7. JVM 专题十八:垃圾回收(二)垃圾回收相关算法

    1. 标记阶段 1.1 引用计数算法 1.1.1 对象存活判断 在堆里存放着几乎所有的Java对象实例,在GC执行垃圾回收之前,首先需要区分出内存中哪些是存活对象,哪些是已经死亡的对象.只有被标记为己 ...

  8. JVM垃圾回收(二)- Minor GC vs Major GC vs Full GC

    Minor GC vs Major GC vs Full GC 垃圾回收的活动会清理对内存中的不同区域,这些事件一般被称为Minor,Major以及Full GC events.本章我们会讨论这些清理 ...

  9. 《垃圾回收的算法与实现》——Python垃圾回收

    Python垃圾回收 python采用引用计数法进行垃圾回收 Python内存分配 python在分配内存空间时,在malloc之上堆放了3个独立的分层. python内存分配时主要由arena.po ...

随机推荐

  1. C#-VS字符串、日期、时间和时间段

    小知识 哈希表,内存中的对象,用速度很快的哈希表当字典表,记录主键和内容. @,遇到转义字符,不转义,直接输出,即就是.转义字符是反斜杠/ 全部的内置类型都用类和结构描述.值类型用结构,引用类型用类. ...

  2. jQueryUI datepicker 报错: TypeError: inst is undefined

    前提:要引用的js等都引用好了 调用日期控件的input: <input id="starttime" name="starttime" class=&q ...

  3. Linux下配置Nginx(在root的/etc/rc.local里配置开机启动功能http://tengine.taobao.org/)

    上面是下载的包下载地址 http://tengine.taobao.org/download_cn.html nginx官网http://nginx.org/ 下一步 下一步 其中remote为重要属 ...

  4. Flash CC2015软件安装教程

    FLCC2015/64位下载地址: 链接:https://pan.baidu.com/s/1c1WoTTu 密码:k4hn 软件介绍: Flash是一种动画创作与应用程序开发于一身的创作软件.Flas ...

  5. matlab的特殊字符(上下标和希腊字母等)

    'T=25\circC',(摄氏度) 下标用 _(下划线) 上标用^ (尖号) 希腊字母等特殊字符用 α \alpha β \beta γ \gamma θ \theta Θ \Theta Г \Ga ...

  6. Kafka send问题

    kafka 在send之后不会立即把消息发送到broker.会把消息发到producer所在电脑内存里,后端的IOThread会扫描内存,并从中取出消息进行消费. 在调用close()或者flush( ...

  7. NetCore入门篇:(三)Net Core项目Nuget及Bower包管理

    一.创建项目 1.如何创建项目,参照上一篇文章 二.程序包介绍 1.Net Core的程序包分前后端两种,后端用nuget,前端用bower. 2.与Net 不同,Net Core引用nuget包时, ...

  8. Ocelot中文文档入门

    入门 Ocelot仅适用于.NET Core,目前是根据netstandard2.0构建的,如果Ocelot适合您,这个文档可能会有用. .NET Core 2.1 安装NuGet包 使用nuget安 ...

  9. Backbone学习笔记 - Model篇

    2 Model 在Backbone中,Model用于存储核心数据,可以将数据交互相关的逻辑代码放在这里.基本形式如下: var Human = Backbone.Model.extend({ init ...

  10. sqlServer 查询表中31到40的记录,考虑id不连续的情况

    SQL   查询表中31到40的记录,考虑id不连续的情况 写出一条sql语句输出users表中31到40记录(数据库为SQL Server,以自动增长的ID作为主键,注意ID可能不是连续的)? -- ...