Java - CMS 与 G1 垃圾收集器

标签 java garbage-collection g1gc concurrent-mark-sweep

cms 和 g1 垃圾收集器之间的区别是什么使 g1 更好?
大部分地方都说这是因为在G1中,堆被划分为区域
然后将区域集合标记为年轻/年老代
并且 gc 在少数区域上运行,而不是在整个堆上运行。我试图进一步了解这一点,并有更多的问题:

  • 当年轻的 gc 运行时(即停止世界),它会在所有年轻代区域上运行
    这意味着整个堆的年轻部分和年轻代的不少区域。
    那么它所花费的时间与CMS相同吗?
  • 增量压缩 - 混合集合 - 现在这是我认为 G1 有优势的地方,因为
    整个堆的并发标记不断发生,并且有混合的 gc 周期运行
    所有年轻区域 + 少数老区域(垃圾最多的区域)。所以它一直在清除垃圾
    老年代也是如此,而不是等待 Full gc 发生。这是正确的吗 ?

  • 上述几点是否正确?还有哪些其他差异使 g1 更好?

    最佳答案

    我将添加一些我知道的原因。

  • 暂停目标时间

  • 您可以有效指导G1尽最大努力在暂停目标时间内完成工作。在内部,它将根据以前收集的统计数据选择要处理的区域数量。因此,它也会调整区域的大小。你不能用 CMS 做到这一点.
  • memset
  • CMS只有一个 card table内部结构,这意味着它需要始终被完全扫描。另一方面G1用途 Remembered Sets ,它们的尺寸较小,并且可以(快速)告知需要扫描哪些其他区域作为当前区域的一部分。
  • 混合系列

  • 是的,G1可以扫描年轻人加上一小部分老年人 - 称为 mixed collections (您可以通过标志配置大小),但这意味着它比简单地完全扫描旧的要快得多。
  • 分片

  • 很可能是早期开始理论工作的最大触发因素 G1 ,至少我的“年长”队友与 CMS 一起工作了很多| ,说这是最大的痛苦之一。 CMS根本不做任何压缩。当对象无法移动到 old generation (因为那一代人的“差距”太小) - 一切都停止了,需要处理这个空间。这变得非常昂贵并且花费了大量时间。另一方面,每个G1循环在移动 Activity 对象时进行压缩并留下空白区域。

    可能还有许多我不知道的其他原因。

    关于Java - CMS 与 G1 垃圾收集器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65536661/

    相关文章:

    java - 我们应该考虑哪些 build.gradle 文件,为什么?

    java - 将实际命令作为参数传递 Java

    java - 解释在 JBoss 服务器上观察到的 JVM 垃圾收集

    java - 为什么启用 G1 垃圾收集器时最大堆大小不正确?

    java - 为什么 G1GC 日志中对堆使用情况的描述不同

    java - izpack 和 launch4j : Invalid uninstaller

    java - 更改 Android 中缓存文件的外观

    performance - 为什么Gradle构建Kotlin源代码会暂停约3秒 “forcing System.gc()”?

    garbage-collection - 您如何管理临时目录以确保在程序关闭时将其删除?

    Java 元空间 Full GC