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