FGC触发时机?
- 老年代空间满;
- 永久代空间满;
- 堆外内存达到上限;
对象进入老年代的几种情况
- 长期存活对象(生存周期超过设置阈值,默认15);
- 大对象(避免在Young区来回复制);
- Survivor溢出(Eden和From Survivor存活对象大小超过了To Survivor大小);
为什么大对象直接进入老年代?
- 避免大对象在Survivor的回复制,效率低下;
- 防止Survivor溢出对象进入老年代,增加FGC频率;
Serial收集器优缺点和适用场景
优点:简单高效;
缺点:单线程执行,并且来及回收时会暂停所有应用线程Stop he World;
适用场景:Client模式下的Java应用;
ParNew收集器优缺点和适用场景
优点:多线程执行垃圾回收;
缺点:仍会Stop the World;
适用场景:与CMS配合使用;
Parallel Scavenge+ Parallel Old优缺点和适用场景
优点:吞吐量优先+自适应大小调整;
缺点:仍会Stop the World;
适用场景:关注吞吐量的后台应用;
Parallel Scavenge的自适应大小调整策略
-XX:AdaptiveSizePolicy能够自动将Eden与Survivor比例,晋升老年代阈值等参数调整到最佳。
CMS优缺点和适用场景
优点:低延时;
缺点:只能与ParNew、Serial配合使用;容易产生空间碎片,导致提前出发FGC;
适用场景:关注延时的应用,常见于B/S模式;
为什么CMS低延时?
最耗时的两个阶段(并发标记和并发清除)和应用线程一起并发执行的,极大地缩短了停顿时间;
CMS空间碎片的解决方案
思路:FGC达到一定次数后进行空间碎片整理(Stop the World),如果每次FGC后进行整理会增加停顿时间;
设置:-XX:UseCMSCompactAtFullCollection 与 -XX:CMSFullGCsBeforeCompaction=n
CMS触发时机
当老年代空间占用率达到-XX:CMSInitiatingOccupancyFraction设定的阈值后,会触发CMS开始垃圾回收,JDK1.6之后默认值为92%。CMSInitiatingOccupancyFraction设定值过小会增加FGC频率,过大会产生“Concurrent Mode Failure”,导致Serial Old被启用,增加FGC时间。
G1优缺点和适用场景
介绍:G1是准备替代CMS的下一代垃圾收集器;
优点:
- 没有空间碎片,使用标记-整理算法;
- 可预测的停顿时间,CMS和G1都最求低停顿,G1还能控制GC的时间上限;
缺点:没有经过大规模商业应用的验证;
适用场景:
- 高配置的服务端(多核、大内存);
- 可控的GC停顿时间;
参考: