标记压缩算法

其分为两个阶段标记阶段,和压缩阶段.其中标记阶段和标记清除算法的标记阶段是一样的.

  • 对压缩算法来说,他的工作就是移动所有的可达对象到堆内存的同一区域中,使它们紧凑的排列在一起,从而将所有非可达对象释放出来的空闲内存集中在一起,以防出现标记清除算法的弊端.

在压缩阶段,由于要移动可达对象,那么就要考虑移动对象时候的顺序问题,一般分为一下三种:

  1. 任意顺序,不考虑原先对象的排列顺序,也不考虑对象之间的引用关系,随意移动可达对象,这样可能会有内存访问的局部性问题.
  2. 线性顺序,在重新排列对象时,会考虑到对象之间的引用关系,例如对象A引用了对象V,那么就会尽量将对象A,B排列在一起.
  3. 滑动排序,按照原先的排列顺序滑动到堆的另一端.

    现在大部分垃圾回收算法都是按照任意顺序或者是滑动顺序去实现的.

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)

  1. 指针free和scan同时指向起始堆位置,同时scan开始向堆尾移动,目的是要找到被标记的可达对象.

  2. 发现可达对象之后,scan指针对应的位置分配一个额外的空间来存储该可达对象应该迁移到的地址,就是free指针指向的位置0,同时free指针向堆尾移动B对象大小的距离,free指针指向的位置.最后指针继续向前走,直到寻找到下一个可达对象D scan指针指向的位置.

  3. 同理,在可达对象D处分配一块空间来保存对象D应该迁移到的位置,由于B对象已经占用了2个内存单元,所以对象E的迁移地址是从位置2开始,也就是当前free指针指向的位置。

  4. 指针free,scan继续向前移动。

  5. 第一次遍历完后,所有的可达对象都有了对应的迁移地址,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. 修改根对象的引用关系,根对象1引用对象B,对象B的迁移地址为0,于是collector将根对象对B对象的引用指向它的迁移地址 - 位置0, 现在A对象所处的位置。

  2. 同理,对于根对象2,3都执行同样的操作,将它们对其所引用的对象的引用修改为对应的它们所引用的对象的迁移地址。

  3. 通过scan指针遍历堆内存,更新所有的可达对象对其引用对象的引用为其引用对象的迁移地址。比如说,对于可达对象B,它引用了对象D,D的迁移地址是2,那么B直接将其对D对象的引用重新指向2这个位置。

  4. 第二次遍历结束后的对象之间的引用关系。

第三次遍历

第三次遍历则是根据可达对象的迁移地址去移动可达对象,比如说可达对象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-标记压缩算法的更多相关文章

  1. 《垃圾回收的算法与实现》——GC标记-压缩算法

    基本算法 Mark-Compact与Mark-Sweep的第一阶段均为标记活跃对象,第二阶段则不同,压缩算法则是将活跃对象逻辑上移到一起. Lisp2算法 对象头中增加forwarding指针,其用法 ...

  2. Java GC 标记/清除算法

    1) 标记/清除算法是怎么来的? 我们在程序运行期间如果想进行垃圾回收,就必须让GC线程与程序当中的线程互相配合,才能在不影响程序运行的前提下,顺利的将垃圾进行回收. 为了达到这个目的,标记/清除算法 ...

  3. JAVA GC之标记 第五节

    JAVA GC之标记  第五节 OK,我们继续昨天最后留下的问题,什么是标记?怎么标记? 第一个问题相信大家都知道,标记就是对一些已死的对象打上记号,方便垃圾收集器的清理. 至于怎么标记,一般有两种方 ...

  4. jvm系列(三):java GC算法 垃圾收集器

    GC算法 垃圾收集器 概述 垃圾收集 Garbage Collection 通常被称为“GC”,它诞生于1960年 MIT 的 Lisp 语言,经过半个多世纪,目前已经十分成熟了. jvm 中,程序计 ...

  5. Java GC算法 垃圾收集器

    GC算法 垃圾收集器 概述 垃圾收集 Garbage Collection 通常被称为"GC",它诞生于1960年 MIT 的 Lisp 语言,经过半个多世纪,目前已经十分成熟了. ...

  6. [面试] Java GC (未整理完)

    Java GC简介 什么是 GC ? Java程序不用像C++程序在程序中自行处理内存的回收释放.这是因为Java在JVM虚拟机上增加了垃圾回收(GC)机制,用以在合适的时间触发垃圾回收. 你都了解哪 ...

  7. jvm系列三、java GC算法 垃圾收集器

    原文链接:http://www.cnblogs.com/ityouknow/p/5614961.html 概述 垃圾收集 Garbage Collection 通常被称为“GC”,它诞生于1960年 ...

  8. Java虚拟机(二):Java GC算法 垃圾收集器

    概述 垃圾收集 Garbage Collection 通常被称为“GC”,它诞生于1960年 MIT 的 Lisp 语言,经过半个多世纪,目前已经十分成熟了. jvm 中,程序计数器.虚拟机栈.本地方 ...

  9. Java GC机制详解

    垃圾收集 Garbage Collection 通常被称为“GC”,本文详细讲述Java垃圾回收机制. 导读: 1.什么是GC 2.GC常用算法 3.垃圾收集器 4.finalize()方法详解 5. ...

  10. Java GC垃圾回收

    Java的内存分配和回收也主要在Java的堆上进行的,Java的堆中存储了大量的对象实例,所以Java的堆也叫GC堆. Java在垃圾收集的过程中,主要用到了分代收集算法,具体有复制.标记清除.标记压 ...

随机推荐

  1. LightOJ - 1079 Just another Robbery —— 概率、背包

    题目链接:https://vjudge.net/problem/LightOJ-1079 1079 - Just another Robbery    PDF (English) Statistics ...

  2. 使用meld作为git的辅助工具

    原文链接: https://lrita.github.io/2017/05/14/use-meld-as-git-tool/?hmsr=toutiao.io&utm_medium=toutia ...

  3. java Regex匹配及解析文本

    用一个main程序展示下 public static void main(String[] args){       String text = "SSM<br>LOC<b ...

  4. Early Media and Music on Hold

    Early media refers to any media that is played to the initial caller’s phone before the remote party ...

  5. 自己实现的vector

    #include <iostream> #include <memory> using std::cout; using std::endl; using std::alloc ...

  6. CentOS7的安装以及GPT和MBR

    讲到GPT(GUID partition Table)和MBR(Master Boot Record)首先要将一下EFI(Extension Firmware Interface)和BIOS(Basi ...

  7. POJ2182(排队问题)

    Lost Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10695   Accepted: 6865 Descri ...

  8. Java高并发(1)

    1.同步和异步的区别和联系: 所谓同步,可以理解为在执行完一个函数或方法之后,一直等待系统返回值或消息,这时程序是出于阻塞的,只有接收到 返回的值或消息后才往下执行其它的命令. 异步,执行完函数或方法 ...

  9. java枚举类型的优势在哪里?--一个实例

    最近在做一个项目,其中涉及到一组操作,命名为: 1. "add"; 2. "logicDel" 3. "physicDel" 4. &quo ...

  10. [hdu2063]过山车(二分图匹配)

    题意:每个女人有感兴趣的k个男人,过山车两人一组,求最大匹配数. 解题关键:二分图最大匹配.匈牙利算法求解. 1.链式前向星建图 #include<cstdio> #include< ...