G1 比 Java 7 上的默认垃圾收集器慢

G1 slower than default garbage collector on Java 7

我一直在尝试在我的应用程序上使用 G1,并注意到与 java 7u91 上的默认垃圾收集器相比,启动应用程序需要更多时间。另一方面,G1 应该执行的集合较少。

G1 变慢有什么原因吗?我的应用程序在 Solaris 64 位版本上使用 128mb 的最小和最大堆,没有 VM 自定义参数。 (Java 服务器版)

and noticed it takes more time to start an application

这有几个原因

第一:在大多数情况下,默认收集器是并行收集器,也称为吞吐量收集器。就花在 GC 上的墙时间与花在应用程序代码上的墙时间而言,它是最有效的。[1]。它不必承担执行并发工作的额外成本。

G1 主要通过在部分并发收集上花费额外的 CPU 周期来优化大型堆上的暂停时间,这需要您有 CPU 周期备用。吞吐量只是次要目标。

其次:启用G1改变的不仅仅是使用的算法,很多默认设置也改变了。

diff <(java -XX:+UseG1GC -XX:+PrintFlagsFinal) <(java -XX:+PrintFlagsFinal) 显示其他标志如何更改

在 java 8 上,存在以下差异 显着 影响 GC 行为,其中包括:

<     uintx GCTimeRatio                               = 9                                   {product}
>     uintx GCTimeRatio                               = 99                                  {product}
<     uintx MaxGCPauseMillis                          = 200                                 {product}
>     uintx MaxGCPauseMillis                          = 18446744073709551615                    {product}

第三:应用程序启动并不是衡量任何事情的好方法,因为这是一个瞬态事件,堆仍然必须稳定到它的最终大小。收集器的目标是稳态运行,可能会以不同方式处理此类瞬变。


在 "old RISC server" 和 128 MB 的堆大小上,您肯定要坚持使用并行或串行收集器。这样的配置无法从 G1 提供的功能中获益。

[1] 对于 CPU 周期而不是墙上时间,它将是串行收集器。