java - 为什么 G1 垃圾收集器卸载时间随着时间的推移而增加?

标签 java java-8 garbage-collection solaris g1gc

在使用 JDK 8u172 的 Solaris (SPARC) 下运行 Glassfish 时,使用 G1 垃圾收集器时,我遇到了奇怪的行为,即 Remark 阶段的 Unloading 时间很长并且随着时间的推移而增加。

以下是应用程序服务器启动后的日志摘录:

2018-10-18T10:08:28.362+0200: 9528.430: [GC remark 2018-10-18T10:08:28.362+0200: 9528.430: [Finalize Marking, 0.0012164 secs] 2018-10-18T10:08:28.363+0200: 9528.431: [GC ref-proc, 0.1783250 secs] 2018-10-18T10:08:28.541+0200: 9528.609: [Unloading, 1.4087725 secs], 1.5954223 secs] [Times: user=10.79 sys=0.04, real=1.60 secs]

几天后:

2018-10-22T20:24:52.070+0200: 392111.556: [GC remark 2018-10-22T20:24:52.070+0200: 392111.556: [Finalize Marking, 0.0010811 secs] 2018-10-22T20:24:52.072+0200: 392111.557: [GC ref-proc, 0.1432306 secs] 2018-10-22T20:24:52.215+0200: 392111.701: [Unloading, 5.4160564 secs], 5.5672543 secs] [Times: user=41.16 sys=0.06, real=5.57 secs]

如您所见,卸载时间从 1.6 秒增长到 5.6 秒。

这是卸载时间随时间变化的图表:

increasing unloading times over time

正如您所看到的,它随着时间的推移或多或少呈线性增长。

以下是相关的命令行标志:

-XX:+AlwaysPreTouch -XX:GCLogFileSize=10485760 -XX:InitialHeapSize=8589934592 -XX:MaxHeapSize=8589934592 -XX:MetaspaceSize=536870912 -XX:NumberOfGCLogFiles=5 -XX:+PrintGC -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+UnlockDiagnosticVMOptions -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC -XX:+UseGCLogFileRotation -XX:+UseLargePages -XX:+UseLargePagesInMetaspace

标志-XX:+UseLargePagesInMetaspace是在阅读this blog post后添加的,但不幸的是它并不能解决问题。我还看了this other blog postthis question ,但不幸的是,所提出的解决方案似乎都不适用于这种情况。

当 Glassfish 服务器在其他操作系统/架构下运行时,我无法重现此错误。

最佳答案

这是 JDK 中的一个错误:JDK-8199406 : Performance drop with Java JDK 1.8.0_162-b32 .

从错误描述来看,和 this discussion thread ,这个错误:

  • 是 JDK 8u161 中引入的回归,影响垃圾收集
  • 特定于 Solaris:“有报告称 Solaris SPARC 64 上的性能下降”; “在 x86 上速度非常快。
  • 增加类卸载时间:“这是 8u161 中引入的回归,它将客户的类卸载时间从平均 0.65 秒增加到 10 秒。””
  • 已在 JDK 8u181/8u182 中修复。

迁移到 JDK 8u192 修复了该错误,卸载时间现在小得多且恒定:

2018-10-24T11:57:48.479+0200: 96295.786: [GC remark 2018-10-24T11:57:48.480+0200: 96295.786: [Finalize Marking, 0.0012370 secs] 2018-10-24T11:57:48.481+0200: 96295.787: [GC ref-proc, 0.0960026 secs] 2018-10-24T11:57:48.577+0200: 96295.883: [Unloading, 0.2760147 secs], 0.3796341 secs] [Times: user=1.51 sys=0.02, real=0.38 secs]

关于java - 为什么 G1 垃圾收集器卸载时间随着时间的推移而增加?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52966618/

相关文章:

java - 如何为以 3 个数字或连字符结尾的字符串编写正则表达式模式?

Java 8 分区列表

php - 跟踪图像文件的链接或引用并删除未使用的(PHP/数据库)

java - 使用嵌套 for 循环绘制两个颜色的棋盘,其中每个方 block 都是它们自己的对象 (Java)

java - 东西是如何嵌入到浏览器中的?

java - 扩展 JTable 中的键绑定(bind)

caching - 如何使用实例转发器缓存检测类?

java - Stream.forEach 是否尊重顺序流的相遇顺序?

c# - WPF View 模型 GC

c# - 包含具有无限循环的线程的对象的垃圾收集