【问题标题】:Why Major Garbage collection is slower than Minor?为什么主要垃圾收集比次要慢?
【发布时间】:2014-07-06 13:37:56
【问题描述】:

通过这个link 但仍然 对次要和主要 GC 收集中实际发生的情况感到困惑。

假设我在年轻一代中有 100 个对象,其中 85 个对象是无法访问的对象。现在当 Minor GC 运行时, 它将回收 85 个对象的内存并将 15 个对象移至较老的(终身)代。

现在 15 个活动对象存在于老年代,其中 3 个无法访问。说主要 GC 发生。它会保持 15 个对象,并为 3 个无法访问的对象回收内存。据说 Major GC 比 Minor GC 慢。 My question is why ? Is it because of major GC happens on generally greater number of objects than minor as minor gc occurs more frequently than major?

根据major GC should be faster as it needs to do less work 的理解,即从无法访问的对象中回收内存而不是次要 GC,因为 年轻一代死亡率高。

【问题讨论】:

    标签: java garbage-collection


    【解决方案1】:

    1) Minor GC 将首先将 15 个对象移动到幸存者空间之一,例如 SS1,下一次 GC 会将仍然活着的对象移动到 SS2,下一次 GC 会将幸存的对象移回 SS1,依此类推。只有那些在几次(例如 8 次)重定位(次要 GC)中幸存下来的人才能最终进入老年代。

    2) Major GC 仅在 JVM 无法在老年代分配对象时发生,因为其中没有可用空间。为了清理死对象的内存,GC 会遍历老年代中的所有对象,由于老年代比新生代大几倍,它可能会容纳几倍的对象,因此 GC 处理时间会长几倍

    【讨论】:

    【解决方案2】:

    我的问题是为什么?是因为 Major GC 通常发生在比 Minor 更多的对象上,因为 Minor GC 比 Major 更频繁地发生?

    你几乎一针见血。从 Oracle 文章中,强调我的:

    主要收集通常要慢得多,因为它涉及所有活动对象

    因此,主要的 GC 不仅会分析老年代中的这 15 个对象,它还会(再次)遍历年轻代并 permgen 和 GC 堆中的这些区域。 Minor GC 只分析年轻代,所以一般不会有那么多对象要查看。

    据了解,主要 GC 应该比次要 GC 更快,因为它需要做的工作更少(即从无法访问的对象中回收内存),因为年轻代的死亡率很高。

    我想我明白你为什么这么想。我可以想象,在次要 GC 之后很快就会运行主要 GC,此时对象被提升到几乎完整的老年代。因此,年轻一代(大概)不会包含太多需要收集的对象。

    不过,如果我没记错的话,老年代通常比年轻代大,所以 GC 不仅要分析更多的空间,它还必须再次遍历 permgen,以及剩余的年轻代中的对象(再次)。所以这可能就是主要 GC 速度较慢的原因——仅仅是因为有更多的事情要做。您可能可以通过更改生成空间的大小使年轻一代比老一代和永久代都大,从而使主要 GC 比次要 GC 更快,但我认为这不会成为一个常用的设置...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-26
      • 1970-01-01
      • 1970-01-01
      • 2021-12-26
      • 1970-01-01
      • 2017-01-31
      • 1970-01-01
      相关资源
      最近更新 更多