JVM发生CMS GC的 5 种情况,你知道的肯定不全!
从源码上看,这里主要分成两类: (a) Old Gen 空间使用占比情况与阈值比较,如果大于阈值则进行 CMS GC 也就是"occupancy() > initiatingoccupancy()",occupancy 毫无疑问是 Old Gen 当前空间的使用占比,而 initiatingoccupancy 是多少呢?
可以看到当 CMSInitiatingOccupancyFraction 参数配置值大于 0,就是 “io / 100.0”; 当 CMSInitiatingOccupancyFraction 参数配置值小于 0 时(注意,默认是 -1),是 “((100 - MinHeapFreeRatio) + (double)(tr * MinHeapFreeRatio) / 100.0) / 100.0”,这到底是多少呢?是 92%,这里就不贴出具体的计算过程了,或许你已经在某些书或者博客中了解过,CMSInitiatingOccupancyFraction 没有配置,就是 92,但是其实 CMSInitiatingOccupancyFraction 没有配置是 -1,所以阈值取后者 92%,并不是 CMSInitiatingOccupancyFraction 的值是 92。 (b) 接下来没有配置 UseCMSInitiatingOccupancyOnly 的情况 这里也分成有两小类情况: 当 Old Gen 刚因为对象分配空间而进行扩容,且成功分配空间,这时会考虑进行一次 CMS GC; 根据 CMS Gen 空闲链判断,这里有点复杂,目前也没整清楚,好在按照默认配置其实这里返回的是 false,所以默认是不用考虑这种触发条件了。 4.根据增量 GC 是否可能会失败(悲观策略) 什么意思呢?两代的 GC 体系中,主要指的是 Young GC 是否会失败。如果 Young GC 已经失败或者可能会失败,JVM 就认为需要进行一次 CMS GC。
我们看两个判断条件,“incrementalcollectionfailed()” 和 “!getgen(0)->collectionattemptissafe()” incrementalcollectionfailed() 这里指的是 Young GC 已经失败,至于为什么会失败一般是因为 Old Gen 没有足够的空间来容纳晋升的对象。 (编辑:晋中站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |