JVM之优化延迟或响应时间(CMS垃圾回收器)
CMS有几个注意点
- 对象从young代转移到old代的转移率
- CMS重新分配内存的概率
- CMS回收对象时候产生的old代的分隔,这个会在可获得的对象中间产生一些空隙,从而导致了分隔空间
CMS的缺点
- 从年轻代转移到老年代会更慢,所以减少从年轻代到老年代的转移
- 内存碎片
- 当从吞吐量垃圾回收器(Throughput)迁移到CMS的时候,有可能会获得更慢的MinorGC,由于对象从young代转移到old会更慢 ,由于CMS在old代里面分配的内存是一个不连续的列表,相反,吞吐量垃圾回收器只是在本地线程的分配缓存里面指定一个指针。
- 由于old代的垃圾回收线程和应用的线程是尽可能的并发运行的,所以吞吐量会更小一些。然而,最坏的延迟的频率会少很多,由于在old代的不可获取的对象能够在应用运行的过程被垃圾回收,这样可以避免old代的空间溢出。
- 使用CMS,如果old代能够使用的空间有限,单线程的stop-the-world压缩垃圾回收会执行。这个的执行时间比吞吐量垃圾回收更长。
解决内存碎片的方法
- 压缩old代,压缩old代空间是通过stop-the-world垃圾回收压缩完成的,就像前面所说的那样,stop-the-world垃圾回收会执行很长时间,会严重影响应用的响应时间,应该避开。
- 最大内存原则,加大老年代内存,让其有足够的轮换空间。
- 减少对象从young代移动到old的概率,就是减少MinorGC,应用MinorGC回收原则。可以设置任期阈值,也就是对象的岁数。
注意:
不推荐把最大任期阀值设定成0或者超过15,这样会导致GC的低效率。
监控任期阈值
设置阈值:-XX:MaxTenuringThreshod=<n>
监控阈值:-XX:+PrintTenuringDistribution
下面是一个输出的例子:
Desired survivor size 8388608 bytes, new threshold 1 (max 15)
- age 1: 16690480 bytes, 16690480 total
在这里例子中,最大任期阀值被设置为15,(通过max 15表示)。内部计算出来的任期阀值是1,通过threshold 1表示。Desired survivor size 8388608 bytes表示一个survivor的空间大小。目标survivor的占有率是指目标survivor和两个survivor空间总和的比值。怎么样指定期望的survivor空间大小在后面会详细介绍。在第一行下面,会列出一个对象的岁数列表。每行会列出每一个岁数的字节数,在这个例子中,岁数是1的对象有16690480字节,而且每行后面有一个总的字节数,如果有多行输出的话,总字节数是前面的每行的累加数。后面举例说明。
使用CMS的关键
- 老年代有足够的空间
- 启动CMS垃圾回收的周期开始时机(快到回收对象的速度比转移对象的速度块,设置老年代占用比例,当去到这个比例就CMS回收,-XX:CMSInitiatingOccupancyFraction=<percent> 和 -XX:+UseCMSInitiatingOccupancyOnly )
- 太大的年轻代会导致Minor GC的时间过长,有时宁愿产生内存碎片也要保证最基本的延迟不要太大
-Xmx1536m -Xms1536m -Xmn512m -XX:+UseCMSInitiatingOccupancyOnly
-XX:CMSInitiatingOccupancyFraction=51
CMS暂停时间优化
CMS有两个阶段是stop - the - world,
- 初始标记阶段,比较快
- 再标记,设置某个配置,在Full GC之前再做一次Minor GC,减少对象
CMS吞吐量优化
- 额外命令
- 增加年轻代大小,减少Minor GC频率
- 增加老年代大小,减少Full GC的频率,减少碎片
- 优化堆大小,减少年轻代移动到老年代的对象
- 优化CMS周期启动
注意:
主要的目的是减少垃圾回收器占用CPU时间,把CPU留给应用计算
参考:
http://blog.csdn.net/zhoutao198712/article/details/7831880
http://blog.csdn.net/zhoutao198712/article/details/7841977