最近发现服务cpu消耗不是很稳定,在150%~600%之间不停跳动,以前没有这种情况,check了一下,是old区内存不太够导致每隔一小段时间cms gc了,old区内存不够的主要原因是服务需要加载的数据变多了,使得old区频繁gc;
用 jmap -heap $pid 可以看到当old区占比超过92%时就会触发cms,以前一直以为cms触发是68%,查了下资料,jdk5默认68%,jdk6默认92%;这个需要注意一下;当默认92%时,服务还会发生promotion failed,此时会消耗大量的时间用来full gc;
正确的做法是:
1.增大old区,从原先10G增大到13G,原年轻代2G保持不变,减少cms gc次数;
2.设置CMSInitiatingOccupancyFraction参数,基本满足(Xmx-Xmn)*(100- CMSInitiatingOccupancyFraction)/100>=Xmn即可(Xmx为堆大小,Xmn为年轻代大小),这样能保证即使在cms gc时候old区也能接受来自于年轻代gc的对象,这样就不会触发promotion failed;简单计算一下,CMSInitiatingOccupancyFraction<85就不会触发了,个人暂时设置84,因为old区需要存储一些索引类数据或者缓存,设置太小容易频繁cms gc;
Good night.