我一直在尝试在我的应用程序上使用 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}
第三:应用程序启动并不是衡量任何事情的好方法,因为这是一个 transient 事件,并且堆仍然需要确定其最终大小。收集器的目标是稳态运行,并且可能会以不同的方式处理此类 transient 。
在“旧的 RISC 服务器”和堆大小为 128 MB 的情况下,您肯定希望坚持使用并行或串行收集器。这样的配置并不能从 G1 提供的功能中受益。
[1] 对于 CPU 周期而不是挂钟时间,它将是串行收集器。
关于java - G1 比 Java 7 上的默认垃圾收集器慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35421662/