阅读《深入理解Java虚拟机 JVM高级特性与最佳实践》的读书笔记
Serial收集器
单线程收集器,并且会暂停其他所有的工作线程(Stop The World)
优点:简单而高效,对限定单个CPU的环境非常适合,Client模式下的默认新生代收集器
ParNew收集器
Serial收集器的多线程版本,其他行为和参数设置与Serial收集器完全一致。是server模式下首选新生代收集器,他能与老年代收集器CMS配合工作。默认开启的收集线程与CPU数量相同
-XX:ParallelGCThreads 设置线程数
Parallel Scavenge收集器
关注吞吐量(运行用户程序所占的比重),主要针对CPU密集型应用,可以高效利用CPU
-XX:MaxGCPauseMillis 最大GC暂停毫秒数
-XX:GCTimeRatio GC时间所占比重
收集器将尽力保证GC时间不超过设定值,但是这是以牺牲吞吐量和新生代空间换取的:新生代越小收集时间越小,导致GC更频繁,吞吐量也就下降了。
-XX:+UseAdaptiveSizePolicy 开关参数,开启后不需要手动指定-Xmn、-XX:SurvivorRatio、-XX:PretenureSizeThreshold等参数,jvm会动态调整
Serial Old收集器
Serial收集器的老年代版本,单线程收集器,使用“标记-整理”算法,主要用于Client模式。另外一个主要作用:作为CMS收集器的后备预案,当发生Concurrent Mode Failure时使用。
Parallel Old收集器
Parallel Scavenge收集器的老年代版本,多线程和“标记-整理”算法。在注重吞吐量和CPU资源敏感场合,优先考虑 Parallel Scavenge和Parallel Old。
CMS收集器
关注最短停顿时间为目标的收集器,注重服务响应速度,更好的用户体验。使用“标记-清除”算法。分为4个步骤
初始标记、并发标记、重新标记、并发清除
其中 初始标记、重新标记仍需要“Stop The World”,耗时长的并发标记和并发清除是可以与用户线程一起工作。
并发低停顿收集器
缺点:
1、对CPU资源非常敏感。默认启动线程数是(CPU数+3)/ 4。当CPU在4个以上时,并发回收最多占用不超过25%的CPU资源,但是当CPU不足4个时,差不多占用一半的CPU资源,如果此时负载较大时,对用户线程来说很有压力。
2、存在失败风险,从而导致另外一次fullGC,并且会临时使用Serial Old收集器。因为CMS工作时,需要预留足够的内存空间给用户线程使用,默认在68%时激活GC。
-XX:CMSInitiatingOccupancyFraction 触发GC的百分比,适当提高,可以降低回收次数,设的太高很容易导致“Concurrent Mode Failure”,性能反而下降
3、清除算法容易导致空间碎片。碎片过多会导致在老年代还有很多剩余空间时大对象无法分配,不得不提前触发FullGC。
-XX:+UseCMSCompactAtFullCollection 开启后,在FullGC后进行碎片整理,会增大停顿时间
-XX:CMSFullGCsBeforeCompaction 设置多少次FullGC后进行一次压缩处理。
G1收集器
“标记-整理”算法,可以非常精确的控制停顿,实现在基本不牺牲吞吐量的前提下完成低停顿的内存回收。G1将整个java堆(包括新生代、老年代)划分为多个固定大小的独立区域(Region),并跟踪这些区域的垃圾,维护一个优先列表,优先回收垃圾最多的区域。