加入收藏 | 设为首页 | 会员中心 | 我要投稿 应用网_丽江站长网 (http://www.0888zz.com/)- 科技、建站、数据工具、云上网络、机器学习!
当前位置: 首页 > 综合聚焦 > 资源网站 > 空间 > 正文

JVM发生CMS GC的 5 种情况,你知道的肯定不全!

发布时间:2019-06-13 07:17:02 所属栏目:空间 来源:涤生YQ
导读:副标题#e# 经常有同学会问,为啥我的应用 Old Gen 的使用占比没达到 CMSInitiatingOccupancyFraction 参数配置的阈值,就触发了 CMS GC,表示很莫名奇妙,不知道问题出在哪? 其实 CMS GC 的触发条件非常多,不只是 CMSInitiatingOccupancyFraction 阈值触发

从源码上看,这里主要分成两类: (a) Old Gen 空间使用占比情况与阈值比较,如果大于阈值则进行 CMS GC 也就是"occupancy() > initiatingoccupancy()",occupancy 毫无疑问是 Old Gen 当前空间的使用占比,而 initiatingoccupancy 是多少呢?

  1. _cmsGen ->init_initiating_occupancy(CMSInitiatingOccupancyFraction, CMSTriggerRatio); 
  2. ... 
  3. void ConcurrentMarkSweepGeneration::init_initiating_occupancy(intx io, uintx tr) { 
  4. assert(io <= 100 && tr <= 100, "Check the arguments"); 
  5. if (io >= 0) { 
  6. _initiating_occupancy = (double)io / 100.0; 
  7. } else { 
  8. _initiating_occupancy = ((100 - MinHeapFreeRatio) + 
  9. (double)(tr * MinHeapFreeRatio) / 100.0) 
  10. / 100.0; 

可以看到当 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。

  1. bool incremental_collection_will_fail(bool consult_young) { 
  2. // Assumes a 2-generation system; the first disjunct remembers if an 
  3. // incremental collection failed, even when we thought (second disjunct) 
  4. // that it would not. 
  5. assert(heap()->collector_policy()->is_two_generation_policy(), 
  6. "the following definition may not be suitable for an n(>2)-generation system"); 
  7. return incremental_collection_failed() || 
  8. (consult_young && !get_gen(0)->collection_attempt_is_safe()); 

我们看两个判断条件,“incrementalcollectionfailed()” 和 “!getgen(0)->collectionattemptissafe()” incrementalcollectionfailed() 这里指的是 Young GC 已经失败,至于为什么会失败一般是因为 Old Gen 没有足够的空间来容纳晋升的对象。

(编辑:应用网_丽江站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章
    热点阅读