Java-GC-标记压缩算法
标记压缩算法
其分为两个阶段标记阶段,和压缩阶段.其中标记阶段和标记清除算法的标记阶段是一样的.
- 对压缩算法来说,他的工作就是移动所有的可达对象到堆内存的同一区域中,使它们紧凑的排列在一起,从而将所有非可达对象释放出来的空闲内存集中在一起,以防出现标记清除算法的弊端.
在压缩阶段,由于要移动可达对象,那么就要考虑移动对象时候的顺序问题,一般分为一下三种:
- 任意顺序,不考虑原先对象的排列顺序,也不考虑对象之间的引用关系,随意移动可达对象,这样可能会有内存访问的局部性问题.
- 线性顺序,在重新排列对象时,会考虑到对象之间的引用关系,例如对象A引用了对象V,那么就会尽量将对象A,B排列在一起.
- 滑动排序,按照原先的排列顺序滑动到堆的另一端.
现在大部分垃圾回收算法都是按照任意顺序或者是滑动顺序去实现的.
Two-Finger算法
其实质是任意顺序移动,其最适合处理包含固定大小对象的内存区域.
该算法需要遍历堆内存两次,第一次是将堆尾的可达对象移动到堆开始的空闲内存单元(所以在前面说,最适合固定对象长度).第二次遍历则需要修改可达对象的引用,因为一些可达对象已经被移动到别的地址,而原先引用它们的对象还指向之前的地址.在这两次的遍历过程中,首位两个指针分别从对的头尾两个位置向中间移动,直至两个指针相遇.
LISP2算法
lisp2算法是一种应用更加广泛的压缩算法,它属于滑动顺序算法的一种.他和二指算法的不同之处在于它还可以处理大小不同的对象,而不是固定大小的对象(因此适用范围更加广泛).同时,计算出来的可达对象的迁移地址需要额外的空间进行存储而不是复写原先对象所在的位置.最后Lisps2需要三次堆内存的遍历.
第一次遍历
collector仅仅计算和记录可达对象应该迁移过去的地址.
compact():
computeLocations(HeapStart,HeapEnd,HeapStart)
updateReferences(HeapStart,HeapEnd)
relocate(HeapStart,HeapEnd)
computeLocations(start,end,toRegion):
scan <- start
free <- toRegion
while scan < end
if isMarked(scan)
forwardingAddress(scan) <- free
free <- free + size(scan)
scan <- scan + size(scan)

指针free和scan同时指向起始堆位置,同时scan开始向堆尾移动,目的是要找到被标记的可达对象.
发现可达对象之后,scan指针对应的位置分配一个额外的空间来存储该可达对象应该迁移到的地址,就是free指针指向的位置0,同时free指针向堆尾移动B对象大小的距离,free指针指向的位置.最后指针继续向前走,直到寻找到下一个可达对象D scan指针指向的位置.
同理,在可达对象D处分配一块空间来保存对象D应该迁移到的位置,由于B对象已经占用了2个内存单元,所以对象E的迁移地址是从位置2开始,也就是当前free指针指向的位置。
指针free,scan继续向前移动。
第一次遍历完后,所有的可达对象都有了对应的迁移地址,free指针指向位置9,因为所有的可达对象总共占了9个单元大小的空间。
第二次遍历
第二次遍历主要是修改对象之间的引用关系,基本和二指算法的第二次遍历一样.
updateReferences(start,end):
for each fld in Roots
ref <- *fld
if ref != null
*fld <- forwardingAddress(ref)
scan <- start
while scan < end
if isMarked(scan)
for each fld in Pointers(scan)
if *fld != null
*fld <- forwardingAddress(*fld)
scan <- scan + size(scan)

修改根对象的引用关系,根对象1引用对象B,对象B的迁移地址为0,于是collector将根对象对B对象的引用指向它的迁移地址 - 位置0, 现在A对象所处的位置。
同理,对于根对象2,3都执行同样的操作,将它们对其所引用的对象的引用修改为对应的它们所引用的对象的迁移地址。
通过scan指针遍历堆内存,更新所有的可达对象对其引用对象的引用为其引用对象的迁移地址。比如说,对于可达对象B,它引用了对象D,D的迁移地址是2,那么B直接将其对D对象的引用重新指向2这个位置。
第二次遍历结束后的对象之间的引用关系。
第三次遍历
第三次遍历则是根据可达对象的迁移地址去移动可达对象,比如说可达对象B,它的迁移地址是0,那么就将其移动到位置0,同时去除可达对象的标记,以便下次垃圾收集。
relocate(start,end):
scan <- start
while scan < end
if isMarked(scan)
dest <- forwardingAddress(scan)
move(scan,dest) //将可达对象从scan位置移动到dest位置
unsetMarked(dest)
scan <- scan + size(scan)

Java-GC-标记压缩算法的更多相关文章
- 《垃圾回收的算法与实现》——GC标记-压缩算法
基本算法 Mark-Compact与Mark-Sweep的第一阶段均为标记活跃对象,第二阶段则不同,压缩算法则是将活跃对象逻辑上移到一起. Lisp2算法 对象头中增加forwarding指针,其用法 ...
- Java GC 标记/清除算法
1) 标记/清除算法是怎么来的? 我们在程序运行期间如果想进行垃圾回收,就必须让GC线程与程序当中的线程互相配合,才能在不影响程序运行的前提下,顺利的将垃圾进行回收. 为了达到这个目的,标记/清除算法 ...
- JAVA GC之标记 第五节
JAVA GC之标记 第五节 OK,我们继续昨天最后留下的问题,什么是标记?怎么标记? 第一个问题相信大家都知道,标记就是对一些已死的对象打上记号,方便垃圾收集器的清理. 至于怎么标记,一般有两种方 ...
- jvm系列(三):java GC算法 垃圾收集器
GC算法 垃圾收集器 概述 垃圾收集 Garbage Collection 通常被称为“GC”,它诞生于1960年 MIT 的 Lisp 语言,经过半个多世纪,目前已经十分成熟了. jvm 中,程序计 ...
- Java GC算法 垃圾收集器
GC算法 垃圾收集器 概述 垃圾收集 Garbage Collection 通常被称为"GC",它诞生于1960年 MIT 的 Lisp 语言,经过半个多世纪,目前已经十分成熟了. ...
- [面试] Java GC (未整理完)
Java GC简介 什么是 GC ? Java程序不用像C++程序在程序中自行处理内存的回收释放.这是因为Java在JVM虚拟机上增加了垃圾回收(GC)机制,用以在合适的时间触发垃圾回收. 你都了解哪 ...
- jvm系列三、java GC算法 垃圾收集器
原文链接:http://www.cnblogs.com/ityouknow/p/5614961.html 概述 垃圾收集 Garbage Collection 通常被称为“GC”,它诞生于1960年 ...
- Java虚拟机(二):Java GC算法 垃圾收集器
概述 垃圾收集 Garbage Collection 通常被称为“GC”,它诞生于1960年 MIT 的 Lisp 语言,经过半个多世纪,目前已经十分成熟了. jvm 中,程序计数器.虚拟机栈.本地方 ...
- Java GC机制详解
垃圾收集 Garbage Collection 通常被称为“GC”,本文详细讲述Java垃圾回收机制. 导读: 1.什么是GC 2.GC常用算法 3.垃圾收集器 4.finalize()方法详解 5. ...
- Java GC垃圾回收
Java的内存分配和回收也主要在Java的堆上进行的,Java的堆中存储了大量的对象实例,所以Java的堆也叫GC堆. Java在垃圾收集的过程中,主要用到了分代收集算法,具体有复制.标记清除.标记压 ...
随机推荐
- 3D焦点图插件
在线演示 本地下载
- linux系统 标准目录及其内容
路径名 操作系统 内容 /bin 所有 最核心的操作系统命令 /boot LS 内核和加载内核所需的文件 /dev 所有 伪终端,磁盘,打印机等的设备项 /etc 所有 关键的启动文件和配置文件 ...
- 常用JS组件整理
1.漂亮的弹出层----artDialog http://aui.github.io/artDialog/ 2.弹出层 ------layer http://sentsin.com/jquery/la ...
- POJ 2503 Babelfish(map,字典树,快排+二分,hash)
题意:先构造一个词典,然后输入外文单词,输出相应的英语单词. 这道题有4种方法可以做: 1.map 2.字典树 3.快排+二分 4.hash表 参考博客:[解题报告]POJ_2503 字典树,MAP ...
- Mybatis-Generator_学习_02_使用Mapper专用的MyBatis Generator插件
源码见:https://github.com/shirayner/tk-mybatis-generator 一.要点 二.具体实现 1.项目结构 2.配置 pm.xml <?xml versio ...
- linkedhashSet和hashSet和TreeSet的区别(转)
Set接口Set不允许包含相同的元素,如果试图把两个相同元素加入同一个集合中,add方法返回false.Set判断两个对象相同不是使用==运算符,而是根据equals方法.也就是说,只要两个对象用eq ...
- redis cluster 实践总结
最近项目接触到了redis cluster,现在趁着使用做一下总结,记录一下遇到过的问题,简单的概述一下常用到的命令和功能. 本篇文章主要是以运维的角度去讲述如何去更好的规划redis clust ...
- Xcode 中的main.m
在几乎所有的程序开发中程序一般都是从main函数开始运行的,那么IOS程序也不例外,在上图中我们可以看到Xcode为我们生成了一个main.m文件: // // main.m // iOS // // ...
- P2060 [HNOI2006]马步距离
P2060 [HNOI2006]马步距离 数据到百万级别,明显爆搜不行,剪枝也没法剪.先打表.发现小数据内步数比较受位置关系影响,但数据一大就不影响了.大概搜了一个20*20的表把赋值语句打出来.判断 ...
- ogg概叙、架构、进程
一. OGG 概述 OGG 全称Oracle Golden Gate. 历史: Golden Gate公司于1995年成立于美国加州旧金山,它的名称源自旧金山闻名于世的金门大桥.两位创始人Eric F ...