其他分享
首页 > 其他分享> > concurrent mark-sweep generation: 中used和free 数据异常的问题

concurrent mark-sweep generation: 中used和free 数据异常的问题

作者:互联网

事件背景:
同事向我咨询了从jvm监控中看到的现象,大致描述就是:young gc 频繁,但是没有full gc,且堆内存一直保持在近100%的状态,线程变化稳定,CPU的使用率有波动,主要和young gc有关,具体情况见下图1。然后我们就去运维平台,通过jmap平台查看堆内存的使用情况,前面的数据看起来正常,可是在看concurrent mark-sweep generation的时候,数据不正常,如图2。


图1


图2

运维反馈,此为一个bug,官方给出了解释:
https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8033440

大致的意思是使用jdk8、cms gc背景下, 使用jmap命令去查看堆内存的使用情况时,由于计算的差异会导致该问题,解决的方案是更换gc策略(官方解释的有提到),也许更换命令也是可以的。

后续没有深入研究,可能还存在别的处理方案,也可能我对官网的解释有误解,所以仅作参考。
后续深入研究的时候,再补充更新。

关于同事咨询的问题,其实很快就找到了原因:
1、GC策略是 ParNew GC + CMS GC,物理内存是8G,jvm参数配置了-Xmx5120m,-Xmx与之相等,即jvm最大的堆内存是5G,old区约4787MB,young区约333M。由于young 区空间太小,导致了频繁的young gc。
2、加上jvm参数还配置了-XX:+UseCMSInitiatingOccupancyOnly ,但是没有配置-XX:CMSInitiatingOccupancyFraction=80,jvm就默认old区已用空间达到92%的时候,才会触发full gc,如果没有达到这个阈值,就不会出现full GC,堆内存的使用就会越来越大,就出现了图片的那个情形,当然还存在别的触发full GC的情况,这里就先做过多阐述,如果该机器一直这样下去,肯定也会出现full GC。
3、使用jmap堆内存的使用情况时,还看到了这个参数-XX:NewRatio,默认的值为2,但是很明显并没有起作用,经网上搜索,有人说CMS GC中,这个参数默认是不起作用的,需要手工设置,而且如果手工指定了年轻代和整个堆内存的大小后,也是不起作用的。

解决方案:
1、手工设置年轻代的大小和整个堆内存的大小
2、设置CMS full GC的阈值 为80,即配置-XX:CMSInitiatingOccupancyFraction=80

处理结果:效果明显

标签:used,generation,sweep,young,full,gc,内存,jvm,GC
来源: https://www.cnblogs.com/zhangzhiwencoding/p/15965280.html