Bootstrap

深入理解Java虚拟机(六)

介绍垃圾收集算法

1、标记-清除算法:

通过可达性分析算法,标记内存中需要被回收的对象,在标记完成之后,进行清除操作。反过来,也可以标记存活的对象,清除全部未被标记的对象。

优点:算法简单,执行效率高。

缺点:

(1)产生空间碎片化问题,标记,清除之后会产生大量不连续的内存碎片。

(2)执行效率不稳定,执行效率随对象数量增长而降低。

2、标记-复制算法(新生代采用)

主要为了解决:标记-清除算法面对大量可回收对象执行效率低的问题。把内存按照1:1划分两个相同的分区。当一块内存用完,就把存活的对象复制到另外一块上面,然后再把已使用过的空间一次清理掉。

但是极端情况,如果内存中多数对象都是存活的,这种算法将会产生大量的内存空间复制的开销。

优点:算法简单,执行效率高。

缺点:内存缩小为原来的一半,空间浪费太多。

资料:IBM公司曾有一项专门研究对新生代“朝生夕灭”的特点做了更量化的诠释——新生代中的对象有98%熬不过第一轮收集。因此不需要按照1:1的比例来划分新生代的内存空间。

当Survivor 不能够存放 10%的存活对象的时候,“逃生门”的安全设计,需要依赖其他的内存区域进行分配担保,通常是老年代。

3、标记-整理算法(老年代采用)

标记-复制算法在对象存活率较高时,就要进行较多的复制操作,效率将会降低。针对老年代对象的存亡特征,采用标记-整理算法。主要是同一块内存把存活的对象向空间一端移动,然后直接清除掉边界以外的内存。

缺点:由于老年代的存活对象比较多,移动一次会导致全程暂停用户应用程序。

方案:相比标记-清除算法产生的碎片化带来问题——用户程序最频繁的操作上增加了额外的负担,影响应用程序的吞吐量。

采用标记清除算法和标记整理算法结合的方式,大多数时间采用清除算法,容忍内存碎片化存在,当内存空间的碎片化程度影响对象分配时,再采用标记-整理算法收集一次。

新的解决方案:收集器使用读屏障(Read Barrier)技术实现了整理过程与用户线程的并发执行。

;