【问题标题】:Java Concurrent and Parallel GCJava 并发和并行 GC
【发布时间】:2008-10-21 00:15:55
【问题描述】:

这篇文章here 建议使用-XX:+UseParNewGC“To enable a parallel young generation GC with the concurrent GC”。

我的困惑是,为了同时启用并行和并发 GC,我应该

  • 使用-XX:+UseParNewGC
  • 同时使用-XX:+UseParNewGC -XX:+UseConcMarkSweepGC ?

PS

我正在使用 JVM 6。

【问题讨论】:

  • 您使用的是哪个 JVM 版本? 1.4.2 和 5 或 6 有一些区别。
  • “年轻一代”的表达可能会引起一些混淆,在这种情况下,这与堆中 Java 对象的年龄有关(与 GC 的现代程度无关)。

标签: java garbage-collection concurrency


【解决方案1】:

由于您链接的文档是针对 1.4.2 VM 的,因此我假设您正在使用它(JVM 5 和 6 的行为不同)。

来自http://java.sun.com/docs/hotspot/gc1.4.2/

如果 -XX:+UseConcMarkSweepGC 用于 命令行然后是标志 UseParNewGC 也设置为 true,如果它 没有以其他方式明确设置 命令行

所以答案是你只需要使用 -XX:+UseConcMarkSweepGC 就可以启用并发收集器和并行年轻代收集器。

编辑:对于 Java 6,相同的标志 (-XX:+UseConcMarkSweepGC) 启用并发收集器。你想要的收集器的选择取决于几件事,你应该测试不同的配置。但是有一些非常一般的指导方针。如果您有单处理器、单线程机器,那么您应该使用串行收集器(某些配置的默认设置,可以使用 -XX:+UseSerialGC 显式启用)。对于您的工作负载基本上受 CPU 限制的多处理器机器,请使用并行收集器。如果您使用 -server 标志,则默认启用此功能,或者您可以使用 -XX:+UseParallelGC 显式启用它。如果您宁愿以缩短 GC 暂停时间为代价,以使用更多总 CPU 时间进行 GC,并且您拥有多个 CPU,则可以使用并发收集器 (-XX:+UseConcMarkSweepGC)。请注意,对于给定的工作负载,并发收集器往往需要比串行或并行收集器更多的 RAM 分配给 JVM,因为可能会发生一些内存碎片。

【讨论】:

  • 我还是不明白,所以要启用并行年轻代 GC 和并发 GC,我必须同时使用 concmarksweepgc 和 parnewgc 还是只使用 concmarksweepgc 可以?
  • Just -XX:+UseConcMarkSweepGC,我认为 UseParNewGC 标志在 Java 6 中没有效果(甚至可能导致错误)。
  • 您可以使用 java -XX:+PrintCommandLineFlags -XX:+UseConcMarkSweepGC -version => -XX:+UseParNewGC 进行检查。 (用 1.6.0_26 测试)。
【解决方案2】:

【讨论】:

    【解决方案3】:

    这篇博文很好地细分了不同的收集器,以及哪些选项有效:http://blogs.oracle.com/jonthecollector/entry/our_collectors

    【讨论】:

      【解决方案4】:

      Java GC 调优基本上是一门黑暗的艺术,但在我的应用程序(运行 50+GB 堆和 16 个物理内核)中,ConcMarkSweep 收集器的速度比 -server 默认值快 3 倍,比默认值快 2.2 倍ParallelOldGC。

      如果您不与其他进程共享计算机(因此只是浪费了空闲内核),请使用 ConcMarkSweepGC。

      【讨论】:

      • 您能否详细解释一下“如果您不与其他进程共享机器(因此只是浪费了空闲内核),请使用 ConcMarkSweepGC。” ?
      【解决方案5】:

      使用 CMS 时,ParNew 是默认的年轻代收集器。您只需指定 -XX:+UseConcMarkSweepGC 即可使用 CMS,默认使用 ParNew。 CMS 是一个很好的收集器,如果避免 GC 抖动具有更高的优先级,但如果吞吐量更重要,例如对于类似批处理的作业,则默认的 SUN 并行收集器会做得更好。

      【讨论】:

        【解决方案6】:

        您不能同时启用两个 GC 选项。我建议您使用优于下一代 GC 的 CMS,与 UseParNewGC 相比。如果您使用 Java 1.7 或更高版本并且堆大小相对较大(例如 > 4GB),请考虑使用 G1。

        【讨论】: