摘自《深入理解Java虚拟机》周志明著
垃圾回收器是GC算法在虚拟机中的具体实现。
HotSpot针对Young Generation和Tenured Generation分别提供了一些回收器,你可以按照你的系统要求来选取合适的组合,
考量因素包括:服务端系统还是客户端系统,追求用户体验还是希望不浪费CPU空间等
HotSpot提供的回收器:
1. Young Generation: Serial, ParNew, Parallel Scavenge
2. Old Generation: Serial Old, CMS, Parallel Old
Serial和Serial Old在GC时会停止其他工作线程(术语:
Stop the world),这样回收效率最高,但代价是用户可能要容忍长时间的停顿;这个组合是Client模式下的默认选项,因为Client模式下一次性需要回收的内存并不大,虽然GC时会有停顿,但停顿时间一般会在一百毫秒以内
ParNew是高版本的Serial,它照样会Stop the world,只不过在多CPU环境下它的表现更好
Parallel Scavenge + Parallel Old组合的目标是为了尽最大可能把CPU精力放在工作上,而不是放在GC上(术语:吞吐率高);它适于在后台运算而不太需要太多交互的任务
CMS(Concurrent Mark Sweep)模式下,GC线程与工作线程同时工作,虽然有时也需Stop the world,但这个停顿时间非常短,因此
CMS模式适用于用户交互的系统,如互联网。
但CMS也有它的缺点:
a.与工作线程并发工作,因此对CPU的并发性要求比较高,最好用在多核(>= 4)的系统中,否则可能得不偿失
b.由于GC的过程中工作线程会产生新的垃圾(floating garbage), 如果等内存塞满了才开始GC,这些新的垃圾就没地方放,所以必须在塞满前就开始GC; 这可能导致GC的频率比较高,更严重的是,如果floating garbage的大小超过了当前所能容纳的空间,JVM会启动一次Full GC(基于Serial Old),这样的停顿时间就很长了。
c.Mark + Sweep会搞出很多碎片来,遇到大对象时,如果没有连续的大内存空间,JVM也会启动一次Full GC