垃圾收集器-周志明先生的深入理解JVM摘录
1 HotSpot的垃圾收集是基于分代的,不同代的内存区域根据其对象生命周期的长短特性选择不同的垃圾收集算法。 HotSpot提供的垃圾收集器: 2 看周志明显示的《深入理解Java虚拟机》第三章垃圾收集器与内存分配,对Young generation的Parallel Scaverge和Tenured generation的CMS印象深刻,简单整理了下相关的知识。H
1 HotSpot的垃圾收集
是基于分代的,不同代的内存区域根据其对象生命周期的长短特性选择不同的垃圾收集算法。HotSpot提供的垃圾收集器:
2 Parallel Scavenge收集器
看周志明显示的《深入理解Java虚拟机》第三章垃圾收集器与内存分配,对Young generation的Parallel Scavenge和Tenured generation的CMS印象深刻,简单整理了下相关的知识。HotSpot的新生代由于生存时间较短,最终存活对象较少,适合拷贝清除算法,老年代由于对象存活时间较长,采用标记整理或者标记清除算法。
Parallel Scavenge收集器,关注吞吐量,这种收集器中吞吐量和停顿时间是不可兼顾的两个方面,在共享CPU的情况下,这两个要素必定是此消彼长的。所谓吞吐量就是CPU用于运行用户代码的时间与CPU总消耗时间的比值;停顿时间在单CPU系统中也是有GC时间的比率决定的。在Java进程中CPU时间由用户线程和GC回收线程轮换使用,二者的和构成了Java进程的CPU总消耗时间。Parallel Scavenge关注的两个要素的计算公式如下:
吞吐量 throughtout=(运行用户代码的时间)/(运行用户代码的时间+垃圾收集时间)
垃圾收集时间的占比=(垃圾收集时间)/(执行用户代码的时间+垃圾收集时间)
停顿时间越短,说明GC消耗CPU时间越长,适合需要和用户交互的程序,能良好地提升用户的体验,另一方面用户代码执行时间也越短,系统吞吐量也越小,但是对用户响应速度也越高。而高吞吐量则可以高效利用CPU更快地完成用户的运算任务,主要适合后台运算交互较少的运用中。
Parallel Scavenge提供了两个参数来精确控制吞吐量,-XX:MaxGCPauseMills,-XX:GCTimeRatio。前者是控制最大垃圾手机停顿时间的毫秒;后者是控制垃圾收集时间在CPU总消耗时间的占比的。GCTimeRatio的默认值是99,这个值的设置,我是这么理解的:就是你期望用户代码的CPU消耗时间和GC的CPU消耗时间的比例。在该收集器中,默认的值是99,即总CPU时间中,用户CPU时间:GC CPU时间=99:1,则GC时间占据总CPU时间的比例为1/(1+99)=1%。
结论,所谓的GCTimeRatio,就是(用户程序CPU时间):(GC CPU时间),通过这个值,可以计算出GC时间在总CPU时间的比率。
ParNew和Parallel Scavenge的区别是,后者关注的是系统吞吐量,也称为吞吐量优先的收集器。会跟当前系统的运行情况收集性能监控信息,动态调整某些参数,以提供最合适的停顿时间或者最大的吞吐量。自适应调节策略是其与ParNew的一个重要区别。
3 CMS收集器
并发标记清除收集器,在多处理器的系统中才能发挥其优势,此时用户线程和GC线程可以在不同的CPU上运行,在CMS并发清理阶段,用户线程还在运行,这存在两个问题:首先,用户线程运行过程中还会产生新的垃圾,但此时CMS已经开始,这些新垃圾并未标记,无法在此次GC中收集,也称为“浮动垃圾”;其次,用户线程既然要运行,就必须有足够的内存空间,所以CMS收集Old区时必须保证为用户线程预留足够的内存。
CMS收集Old区是在Old的使用空间到达一定的比例后就被触发的(不像其它的收集是在Old区几乎完全塞满时才进行),这样确保用户线程有足够的空间。控制参数是:-XX:CMSInitiatingOccupancyFraction,当用户进程在CMS运行过程中出现内存不足时会出现“Concurrent Mode Failure",JVM的后备方案就发生作用,以Serial Old方式重新收集Old区(暂停用户线程)。这个参数设置过高,容易导致用户线程运行过程中内存不足而出现Concurrent Mode Failure。
CMS是采用标记清除的收集算法,还有一个缺点是容易产生空碎片,CMS提供了两个参数来解决这个问题。-XX:UseCMSCompactAtFullCollection开关参数(默认是开启),如果CMS出现无法分配连续内存时,对碎片内存进行整理。-XX:CMSFullGCsBeforeCompation,默认值为0,表示每次进入FullGC之前执行多少次不压缩的GC后跟着执行一次碎片整理。
我的理解是,在CMS默认的参数下,其实CMS已经不是标记清除算法,而是标记整理算法了,我在想为什么一开始不直接使用标记整理算法呢?仔细想想,CMS其实是提供了动态调节算法的机制,应该可以综合获取这两种算法共同的优势,在特定场景下相互切换,以达到最好的效果。
结论:不得不佩服设计这周详的考虑,对存在的问题提供解决方案和应急预案,CMS里面的优秀理念,受教了!
更多推荐
所有评论(0)