IBM 实现使用称为 mark-sweep-compact(MSC)的垃圾收集算法,它是根据三个不同的阶段命名的
标记
表和所有“可达的”或者活动的对象。这个阶段从确定“根”开始,比如线程栈上的对象、Java Native Interface(JNI)局部引用和全局引用等,然后沿着每个引用进行递归,直到所有的引用都做上标记。
清理
清除所有已经分配但没有标记的对象,收回这些对象使用的空间。
压缩
将活动对象移动到一起,去掉堆中的空洞(hole)和碎片。
关于 MSC 算法的细节,请参阅参考资料。(http://www.ibm.com/developerworks/cn/java/i-gctroub/index.html#resources)
并行和并发
虽然垃圾收集本身采用 STW 机制,但最新的 IBM JVM 版本都在多处理器机器上使用多个“帮助器”线程,以便减少每个阶段所花费的时间。因此,在默认情况下,JVM 1.3.0 在标记阶段采用并行模式。JVM 1.3.1 在标记和清理阶段都采用并行模式,在标记阶段还支持一种可选的并发模式,可以使用命令行开关 -Xgcpolicy:optavgpause 切换。撰写本文时,最新版本的 JVM 1.4.0 中有一种递增压缩模式,它并行化了(parallelize)压缩阶段。讨论这些模式时,重要的是要理解并行和并发的区别。
在拥有 N 个 CPU 的多处理器系统中,支持并行模式的 JVM 在初始化的时候会启动 N-1 个垃圾收集帮助器线程。运行应用程序代码的时候,这些线程一直处于空闲状态,只有当启动垃圾收集时才调用它们。在某一特定的阶段,会将一些工作分配给驱动垃圾收集的线程和帮助器线程,因此一共有 N 线程并行地运行在 N-CPU 机器上。如果要禁止并行模式,惟一的方法是使用 -Xgcthreads 参数改变启动的垃圾收集帮助器线程个数。