我一直在尝试在我的应用程序上使用 G1,并注意到与 java 7u91 上的默认垃圾收集器相比,启动应用程序需要更多时间。另一方面,像 G1 应该执行的那样执行的集合更少。
G1速度慢有什么原因吗?我的应用程序使用 128mb 的最小和最大堆,超过 Solaris 64 位版本,VM 没有自定义参数。(Java服务器版)
我一直在尝试在我的应用程序上使用 G1,并注意到与 java 7u91 上的默认垃圾收集器相比,启动应用程序需要更多时间。另一方面,像 G1 应该执行的那样执行的集合更少。
G1速度慢有什么原因吗?我的应用程序使用 128mb 的最小和最大堆,超过 Solaris 64 位版本,VM 没有自定义参数。(Java服务器版)
并注意到启动应用程序需要更多时间
这有几个原因
第一:在大多数情况下,默认的收集器是并行收集器,也称为吞吐量收集器。相对于在应用程序代码中花费的墙时间而言,它是最有效的一种。[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}
第三:应用程序启动并不是衡量任何事情的好方法,因为这是一个瞬态事件,并且堆仍然必须稳定到其最终大小。集电极以稳态运行为目标,并且可能以不同方式处理此类瞬变。
在“旧 RISC 服务器”和 128 MB 的堆大小上,您肯定希望坚持使用并行或串行收集器。这样的配置并不能从 G1 提供的东西中受益。
[1]对于 CPU 周期而不是墙上时间,它将是串行收集器。