垃圾回收(Garbage Collection,GC) 是 java/csharp 等托管型 语言区别于 C/C++ 的主要特征之一。 然而 GC 技术的历史远比这些语言要来得久远,在1960 年诞生于MIT的List是 第一个使用内存动态分配和垃圾回收技术的语言。经过多年的发展, 内存的动态分配与回收技术已经变得相当成熟,查阅了一些资料,了解了 GC 里面几种主要的算法思想,在这边记下 (好记性不如 刷博客啊 )
Mark-Sweep 算法
标记-清除(Mark-Sweep)算法,分为 “标记”和 “清除”两个阶段:第一阶段标记出所有需要回收的对象, 在标记完成之后统一回收掉所有被比标记的对象。 这个算法主要有两个缺点: 1. 标记和清除过程的效率不高 2. 标记清除过后会产生大量不连续的内存碎片。由于空间碎片过多,可能会导致程序在运行过程中需要分配较大的对象时, 无法找到足够的连续内存空间而导致触犯另一次垃圾回收动作。
Coping 算法
复制算法将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将存活的对象复制到另外一块上面,然后把已经使用的内存空间一次清理掉。coping算法每次只对一块进行内存回收,内存分配时不用考虑内存碎片的问题,实现简单,运行高效。这个算法的代价是将内存缩小为了原来一半,空间使用效率不高。
Mark-Compact 算法
复制算法在对象的存活率较高是要执行很多的复制操作,效率就会变得低下。在老年代的对象一般生存周期比较长,一般不适合采用复制算法。针对老年代对象的生存特点,“标记-整理”(Mark-Compact)算法应运而生。 Mark-Compact 算法的标记过程与 Mark-Sweep算法一样,但后续的步骤不是直接回收对象,而是让所存活的对象都向一端移动,然后把端边界以外的内存清理掉。
参考书目:
《深入理解Java虚拟机:JVM高级特性与最佳实践》
《深入java虚拟机》