垃圾回收机制的算法实现——标记压缩算法

一、标记压缩算法

标记压缩算法(Mark Compact),其实就是标记清除和复制算法搞到一块来做更优的实现。它主要分成两个阶段,第一个阶段和标记删除算法一样,进行遍历,标记内存对象的活动状态;第二个阶段是要对整个堆内存进行搜索并将内存活动对象进行压缩填充。
这里需要说明的是,压缩不是将数据或者内存本身压缩,是从整体上看,将内存中的空洞压缩,也就是说,象复制算法一样,不断的把活动内存复制到近似连续的内存空间中去,保证被使用的内存,尽量有空洞存在。当然,这是一种理想状态。

二、优缺点

标记压缩算法的优点这就很明白了:
1、堆的浪费少,利用效率高。这个比单纯的复制优点更明显。
它不再一分为二的应用内存,这样明显的提高了内存的效率,将近可以达到复制算法的一倍以上。
2、其它GC复制算法的优点(除吞吐量外)。

当然,这不代表它没有缺点:
1、压缩的过程需要反复遍历整个堆内存,一般需要三次左右,甚至更多,这样,慢就成了这种方法的一种特点。故而吞吐量会明显低。
2、对大内存不友好,耗时更长。

当然,这不代表着没有优化的余地。不过无论如何优化,结果从整体上看,就是一种平衡的算法。

三、基本应用

标记压缩算法应用的主要步骤如下:
1、标记内存对象状态。
这个在前面提到过了,和标记删除算法一样。就是将内存中的活动对象标记出来。
2、压缩过程:
a、设定forwarding指针,用来指向移动后的新的内存对象的空间地址,初始为NULL
b、在遍历过程中更新forwarding指针
c、将活动内存对象复制到forwarding指向的空间
这里有一个细节需要注意,为了保证内存对象不被覆盖,就需要开辟专门的forwarding空间。

这个实际的算法除了最初的Lisp2算法外,还有改进的Two-Finger 算法、表格算法等,各自在各自的应用场景上有所取舍和提高。

四、总结

其它看GC算法,看得越多,越发现其实是一种不断改良的过程,它不是一场革命,是一场自我修复的改良。这确实在一定程度上不断在提高,可回过头来看,从更高的角度来看,其实它并没有革命性的变化,它只是一种工程技术解决,而没有全新的技术升级换代。

你可能感兴趣的:(Java,GC机制)