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

时间:2021-10-24 01:31:19

I have been trying to use G1 on my applications, and noticed it takes more time to start an application compared to default garbage collector on java 7u91. On the other hand, less collections were execute as G1 is supposed to be.

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

Is there any reason why G1 is slower? My application is using a minimum and maximum heap of 128mb, over Solaris 64bits version with no custom parameters to VM. (Java server edition)

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

1 个解决方案

#1


3  

and noticed it takes more time to start an application

并注意到启动应用程序需要更多的时间

That has several reasons

有几个原因

First: In most cases the default collector is the parallel collector, also known as throughput collector. It is the most efficient one in terms of wall time spent in GC relative to wall time spent in application code.[1]. It does not have to bear the extra costs of performing concurrent work.

首先:在大多数情况下,默认收集器是并行收集器,也称为吞吐量收集器。相对于在应用程序代码中花费的壁时间,它是GC中花费的壁时间中效率最高的一个。它不必承担执行并发工作的额外成本。

G1 primarily optimizes for lower pause times on large heaps by expending additional CPU cycles on partially concurrent collections, which requires that you have CPU cycles to spare. Throughput is only a secondary goal.

G1主要通过在部分并发的集合上增加额外的CPU周期来优化大型堆上较低的暂停时间,这需要您有足够的CPU周期。吞吐量只是次要目标。

Second: enabling G1 changes more than the algorithm used, many default settings are also changed.

第二:启用G1比使用的算法更改得更多,许多默认设置也被更改。

diff <(java -XX:+UseG1GC -XX:+PrintFlagsFinal) <(java -XX:+PrintFlagsFinal) shows how other flags are changed

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

On java 8 there are the following differences that significantly affect GC behavior, among several others:

在java 8中,有以下几个显著影响GC行为的差异:

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

Third: Application startup is not exactly a good way to measure anything since that's a transient event and the heap still has to settle into its final size. Collectors aim for steady-state operation and may handle such transients differently.

第三:应用程序启动并不是一种度量任何东西的好方法,因为这是一个临时事件,堆仍然需要调整到最终大小。收集器以稳态操作为目标,并可能以不同的方式处理此类瞬变物。


On an "old RISC server" and a heap size of 128 MB you definitely want to stick to either the parallel or serial collectors. Such a configuration does not benefit from what G1 has to offer.

在“旧的RISC服务器”和128 MB大小的堆上,您肯定希望坚持使用并行或串行收集器。这样的配置不能从G1提供的内容中获益。

[1] For CPU cycles instead of wall time it would be the serial collector.

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

#1


3  

and noticed it takes more time to start an application

并注意到启动应用程序需要更多的时间

That has several reasons

有几个原因

First: In most cases the default collector is the parallel collector, also known as throughput collector. It is the most efficient one in terms of wall time spent in GC relative to wall time spent in application code.[1]. It does not have to bear the extra costs of performing concurrent work.

首先:在大多数情况下,默认收集器是并行收集器,也称为吞吐量收集器。相对于在应用程序代码中花费的壁时间,它是GC中花费的壁时间中效率最高的一个。它不必承担执行并发工作的额外成本。

G1 primarily optimizes for lower pause times on large heaps by expending additional CPU cycles on partially concurrent collections, which requires that you have CPU cycles to spare. Throughput is only a secondary goal.

G1主要通过在部分并发的集合上增加额外的CPU周期来优化大型堆上较低的暂停时间,这需要您有足够的CPU周期。吞吐量只是次要目标。

Second: enabling G1 changes more than the algorithm used, many default settings are also changed.

第二:启用G1比使用的算法更改得更多,许多默认设置也被更改。

diff <(java -XX:+UseG1GC -XX:+PrintFlagsFinal) <(java -XX:+PrintFlagsFinal) shows how other flags are changed

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

On java 8 there are the following differences that significantly affect GC behavior, among several others:

在java 8中,有以下几个显著影响GC行为的差异:

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

Third: Application startup is not exactly a good way to measure anything since that's a transient event and the heap still has to settle into its final size. Collectors aim for steady-state operation and may handle such transients differently.

第三:应用程序启动并不是一种度量任何东西的好方法,因为这是一个临时事件,堆仍然需要调整到最终大小。收集器以稳态操作为目标,并可能以不同的方式处理此类瞬变物。


On an "old RISC server" and a heap size of 128 MB you definitely want to stick to either the parallel or serial collectors. Such a configuration does not benefit from what G1 has to offer.

在“旧的RISC服务器”和128 MB大小的堆上,您肯定希望坚持使用并行或串行收集器。这样的配置不能从G1提供的内容中获益。

[1] For CPU cycles instead of wall time it would be the serial collector.

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