笔者在一个技术交流群里面看到一位朋友发了一个有趣又诡异的频繁CMS问题的程序,程序代码如下:
设置的JVM参数如下:
-Xmx20m -Xms20m -Xmn10m -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+UseCMSInitiatingOccupancyOnly
-XX:CMSInitiatingOccupancyFraction=75
运行程序,然后用jstat命令查看gc的情况如下:
下面是对该现象讲解一下我个人的思路:
明明JVM已经设置了-XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=75这个参数,从gc情况来看,老年代内存使用率只有60.02%还没有达到75%这个阈值 但是却频繁发生CMS回收了 ,也就是说b1、b2、b3三个对象已经晋升到老年代了,b4先是分配到新生代,后面JVM为了把b4对象从新生代晋升到老年代提前触发了CMS回收,这也就是GC出现频繁CMS的原因了。
当然,以上只是我个人的观点,欢迎大家讲讲自己的看法