【问题标题】:Difference between -XX:+UseParallelGC and -XX:+UseParNewGC-XX:+UseParallelGC 和 -XX:+UseParNewGC 的区别
【发布时间】:2020-05-19 19:07:07
【问题描述】:

它们是年轻代垃圾收集的算法。

第二个 (UseParNewGC) 通过并发的终身垃圾回收自动激活(请参阅Java Concurrent and Parallel GC),但是,这两种并行算法之间有区别吗?

【问题讨论】:

    标签: java jvm-arguments


    【解决方案1】:

    经过大量搜索,我找到的最好的解释来自Java Performance Tuning网站Question of the month: 1.4.1 Garbage collection algorithms, January 29th, 2003

    年轻代垃圾回收算法

    (原始)复制收集器(默认启用)。当这个收集器启动时,所有应用程序线程都停止,复制收集使用一个线程进行(这意味着即使在多 CPU 机器上也只有一个 CPU)。这称为 stop-the-world 收集,因为基本上 JVM 会暂停其他所有操作,直到收集完成。

    并行复制收集器(使用 -XX:+UseParNewGC 启用)。就像原始的复制收藏家一样,这是一个停止世界的收藏家。然而,这个收集器将复制收集并行化到多个线程上,这比用于多 CPU 机器(尽管不适用于单 CPU 机器)的原始单线程复制收集器更有效。与原始的单线程复制收集器相比,此算法可能会将年轻代收集速度提高与可用 CPU 数量相等的倍数。

    并行清除收集器(使用 -XX:UseParallelGC 启用)。这类似于之前的并行复制收集器,但该算法针对多 CPU 机器上的千兆字节堆(超过 10GB)进行了调整。此收集算法旨在最大限度地提高吞吐量,同时最大限度地减少暂停。它有一个可选的自适应调整策略,可以自动调整堆空间的大小。如果你使用这个收集器,你只能在老年代使用原来的mark-sweep收集器(即较新的老年代并发收集器不能和这个年轻代收集器一起工作)。

    从这些信息来看,主要区别(除了 CMS 合作)似乎是 UseParallelGC 支持 ergonomics 而 UseParNewGC 不支持。

    【讨论】:

    【解决方案2】:

    Parallel GC

    • XX:+UseParallelGC 使用并行垃圾回收进行清理。 (在 1.4.1 中引入)
    • XX:+UseParallelOldGC 对完整收集使用并行垃圾收集。启用此选项会自动设置 -XX:+UseParallelGC。 (在 5.0 更新 6 中引入。)

    UseParNewGC

    使用ParNewGC 使用年轻代复制收集器的并行版本 与并发收集器(即如果 -XX:+ UseConcMarkSweepGC 是 在命令行上使用,则标志 UseParNewGC 也设置为 true 如果没有在命令行上明确设置)。

    也许最容易理解的方法是Alexey Ragozin制作的垃圾收集算法的组合

    <table border="1" style="width:100%">
      <tr>
        <td align="center">Young collector</td>
        <td align="center">Old collector</td>
        <td align="center">JVM option</td>
      </tr>
      <tr>
        <td>Serial (DefNew)</td>
        <td>Serial Mark-Sweep-Compact</td>
        <td>-XX:+UseSerialGC</td>
      </tr>
      <tr>
        <td>Parallel scavenge (PSYoungGen)</td>
        <td>Serial Mark-Sweep-Compact (PSOldGen)</td>
        <td>-XX:+UseParallelGC</td>
      </tr>
      <tr>
        <td>Parallel scavenge (PSYoungGen)</td>
        <td>Parallel Mark-Sweep-Compact (ParOldGen)</td>
        <td>-XX:+UseParallelOldGC</td>
      </tr>
      <tr>
        <td>Serial (DefNew)</td>
        <td>Concurrent Mark Sweep</td>
        <td>
          <p>-XX:+UseConcMarkSweepGC</p>
          <p>-XX:-UseParNewGC</p>
        </td>
      </tr>
      <tr>
        <td>Parallel (ParNew)</td>
        <td>Concurrent Mark Sweep</td>
        <td>
          <p>-XX:+UseConcMarkSweepGC</p>
          <p>-XX:+UseParNewGC</p>
        </td>
      </tr>
      <tr>
        <td colspan="2">G1</td>
        <td>-XX:+UseG1GC</td>
      </tr>
    </table>

    结论:

    1. 当您需要 YOUNG 代的并行收集方法时应用 -XX:+UseParallelGCONLY,(仍然)使用 serial-mark-扫描方法作为OLD代集合
    2. YOUNG 代需要并行收集方法时应用 -XX:+UseParallelOldGC(自动设置 -XX:+UseParallelGC)AND OLD一代集合
    3. 当您需要并行收集方法超过YOUNG并且 需要 CMS 方法作为您的收集超过 OLD 时,应用 -XX:+UseParNewGC 和 -XX:+UseConcMarkSweepGC 代记忆
    4. 您不能同时应用 -XX:+UseParallelGC 或 -XX:+UseParallelOldGC 和 -XX:+UseConcMarkSweepGC,这就是为什么您需要 -XX:+UseParNewGC 与 CMS 配对,否则请显式使用 -XX:+UseSerialGC 或 -XX:-如果你想对年轻代使用串行方法,请使用ParNewGC

    【讨论】:

    • 必须是-XX:-UseParallelGC
    • 注意:结论 #1 不再正确。应用-XX:+UseParallelGC 导致对现代 JVM 的年轻和旧 GC 都使用并行 GC。见bugs.openjdk.java.net/browse/…
    【解决方案3】:

    UseParNewGC 通常被称为“并行年轻代收集器”,在所有方面都与并行垃圾收集器 (-XX:+UseParallelGC) 相同,只是它更复杂、更高效。它也可以与“并发低暂停收集器”一起使用。

    请参阅Java GC FAQ,问题 22 了解更多信息。

    请注意,UseParNewGC 存在一些已知错误

    【讨论】:

    • 你知道哪些已知的bug或者哪个JVM版本有它们吗?
    【解决方案4】:

    与 -XX:+UseParallelGC 相比,使用 -XX:+UseParNewGC 和 -XX:+UseConcMarkSweepGC 会导致 Minor GC 的暂停时间更长。

    这是因为,将对象从年轻代提升到老年代将需要运行最佳拟合算法(由于老年代碎片)来找到该对象的地址。
    使用 -XX:+UseParallelGC 时不需要运行这样的算法,因为 +UseParallelGC 只能与 MarkandCompact Collector 一起配置,在这种情况下不会产生碎片。

    【讨论】:

    • 这是一个非常好的见解。您是否进行了任何测试以确认它?
    猜你喜欢
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 2016-11-14
    • 1970-01-01
    • 2019-07-30
    • 1970-01-01
    • 2019-08-04
    • 2015-04-06
    相关资源
    最近更新 更多