Mark Compact GC (Part one: Lisp2)
什么是GC 标记-压缩算法
需要对标记清除和GC复制算法有一定了解
GC标记-压缩算法是由标记阶段和压缩阶段构成。
标记阶段和标记清除的标记阶段完全一样。之后我们要通过搜索数次堆来进行压缩。
Lisp2 算法的对象
Donald E.Knuth
对象结构如图示:

Lisp2 算法在对象头中为forwarding指针留出空间,forwarding指针表示对象的目标地点。(设定forwarding时,还不存在移动完毕的对象)
概要
假设我们在下图所示的状态下执行GC

标记完后状态如下(过程与标记清除算法相同)

压缩完后的状态如下(可以看到,他们现在的位置是挨着的。)

这种算法并不会对对象的顺序产生影响,知识缩小了他们之间的空隙,让他们聚集在堆的一端。
步骤
压缩阶段代码
compaction_phase(){
set_forwarding_ptr() // 设置forwarding指针
adjust_ptr() // 更新指针
move_obj() // 移动对象
}
步骤一:设定forwarding指针
首先程序会搜索整个堆,给活动的对象设定forwarding指针。初始状态下forwarding是NULL。
set_fowarding_ptr(){
scan = new_address = $heap_start
while(scan < $heap_end)
if(scan.mark = TRUE)
scan.forwarding = new_address
new_address += scan.size
scan += scan.size
}
- scan 用来搜索堆中的指针,new_address指向目标地点的指针。
- 一旦scan找到活动对象,forwarding指针就要被更新。按着new_address对象的长度移动。
- 如下图示:

步骤二:更新指针
adjust_ptr(){
for(r :$roots) // 更新根对象的指针
*r = (*r).forwarding
scan = $heap_start
while(scan < $heap_end)
if(scan.mark == TRUE)
for(child :children(scan)) // 通过scan 更新其他对象指针
*child = (*child).forwarding
scan += scan.size
}
- 首先更新根的指针
- 然后重写所有活动对象的指针(对堆进行第二次的搜索)

步骤三:移动对象
搜索整个堆(第三次搜索),再将对象移动到forwarding指针的引用处。
move_obj(){
scan = $free = $heap_start
while(scan < $heap_end)
if(scan.mark == TRUE) // 判断是否是活动对象
new_address = scan.forwarding // 获取对象要移动的地点
copy_data(new_address, scan, scan.size) // 复制对象(移动对象)
new_address.forwarding = NULL // 将forwarding改为NULL
new_address.mark = FALSE // mark改为FALSE
$free += new_address.size // 指针后移
scan += scan.size // 指针后移
}

- 算法不会对对象本身的顺序进行改变,只会把对象集中在堆的一端。
- 算法没有去删除对象,知识吧对象的mark设置为FALSE
- 之后把forwarding改为NULL,标志位改为FALSE,将$free移动obj.size个长度。
优缺点
优点:可有效利用堆
使用整个堆在进行垃圾回收,没啥说的。任何的算法都是有得有失,用时间换空间。或者用空间换时间。重要的是它在这里
适不适用。
缺点:压缩花费计算成本
Lisp2 算法中,对堆进行了3次搜索。在搜索时间与堆大小成正相关的状态下,三次搜索花费的时间是很恐怖。也就是说,它的吞吐量要低于其他算法。时间成本至少是标记清除的三倍(当然不包含mutator)
Mark Compact GC (Part one: Lisp2)的更多相关文章
- Mark Compact GC (Part two :Two-Finger)
目录 Two-Finger算法 前提 概要 步骤一:移动对象 步骤二:更新指针 优缺点 表格算法 概要 步骤一:移动对象群 和 构筑间隙表格 移动对象群 构筑间隙表格 步骤二:更新指针 优缺点 Two ...
- Mark Sweep GC
目录 标记清除算法 标记阶段 深度优先于广度优先 清除阶段 分配 First-fit.Best-fit.Worst-fit三种分配策略 合并 优点 实现简单 与保守式GC算法兼容 缺点 碎片化 分配速 ...
- 1. GC标记-清除算法(Mark Sweep GC)
世界上第一个GC算法,由 JohnMcCarthy 在1960年发布. 标记-清除算法由标记阶段和清除阶段构成. 标记阶段就是把所有的活动对象都做上标记的阶段. 标记阶段就是"遍历对象并标记 ...
- Gson序列化问题导致的内存溢出,tip:Background sticky concurrent mark sweep GC freed
问题原因,如果在json model里面放了非可序列化的对象就会导致这中问题,可序列化的就是那些基础数据类型和集合类型,如果在里面放个Android的Activity或者adapter这类类型字段,变 ...
- copy GC 和 mark & compaction GC的算法异同
先标记 然后 copy GC是,对所有child,判断, 如果child没有被访问过,那么拷贝到新地址,child的forwording指向新地址,child标记为已访问,把自己对child的引用改为 ...
- Java中9种常见的CMS GC问题分析与解决
1. 写在前面 | 本文主要针对 Hotspot VM 中"CMS + ParNew"组合的一些使用场景进行总结.重点通过部分源码对根因进行分析以及对排查方法进行总结,排查过程会省 ...
- GC学习笔记
GC学习笔记 这是我公司同事的GC学习笔记,写得蛮详细的,由浅入深,循序渐进,让人一看就懂,特转到这里. 一.GC特性以及各种GC的选择 1.垃圾回收器的特性 2.对垃圾回收器的选择 2.1 连续 V ...
- 非常详细GC学习笔记
转载:http://blog.csdn.net/fenglibing/article/details/6321453 这是我公司同事的GC学习笔记,写得蛮详细的,由浅入深,循序渐进,让人一看就懂,特转 ...
- 很具体GC学习笔记
GC学习笔记 这是我公司同事的GC学习笔记,写得蛮具体的,由浅入深,循序渐进,让人一看就懂,特转到这里. 一.GC特性以及各种GC的选择 1.垃圾回收器的特性 2.对垃圾回收器的选择 2.1 连续 V ...
随机推荐
- 空暇时候思考之const
对于多数人来说那些const的使用方法比方修饰返回值和修饰參数都应该是十分好理解的下来我要讨论 对于C语言中 #include <stdio.h> void main() { const ...
- JavaScript中的Array对象方法调用
方法concat for 循环与for in 循环 <html> <head> <script type="text/javascript"> ...
- JavaScript编程随笔
尽管说用JS非常多年了,可是却一直停留在肤浅的阶段,对JS的机制原理依旧是一知半解,比如:闭包.尽管能说出一二.却不能说出三四,确实羞愧.近期恶补一番.并将比較与大家分享,希望对大家有些帮助. 闭包 ...
- bzoj1193: [HNOI2006]马步距离(贪心+bfs)
1193: [HNOI2006]马步距离 题目:传送门 题解: 毒瘤题... 模拟赛时的一道题,刚开始以为是一道大难题...一直在拼命找规律 结果.... 还是说正解吧: 暴力的解法肯定是直接bfs, ...
- lightoj--1155-- Power Transmission (最大流拆点)
Power Transmission Time Limit: 2000MS Memory Limit: 32768KB 64bit IO Format: %lld & %llu Sub ...
- 安卓开发--WebView
package com.zhangxi.test01; import android.app.Activity;import android.app.ProgressDialog;import and ...
- Oracle数据库Helper类
using System;using System.Collections.Generic;using System.Data;using System.Data.OleDb;using System ...
- OpenGL编程逐步深入(十)索引绘制
准备知识 OpenGl提供了一些绘图函数.到目前为止我们使用的glDrawArrays绘图函数属于"顺序绘制".这意味着顶点缓冲区从指定的偏移量开始被扫描,每X(点为1,直线为2等 ...
- PostgreSQL Replication之第三章 理解即时恢复(3)
3.3 做基础备份 在上一节中,您已经看到,启用归档只需要几行命令,并提供了极大的灵活性.在本节,我们将看到如何创建一个所谓的基础备份,稍后这可以使用XLOG.一个基本备份是一个最初的数据的拷贝. [ ...
- mybatis-generator-core快速生成实体类和Mapper
日常使用Mybatis少不了和实体类和 Mapper 打交道.除了我们手写来实现,还可以使用 mybatis-generator-core 来快速生成 实体类和 Mapper. 步骤如下: 1.下载 ...