0

我们有一个正在尝试优化延迟的应用程序,我们希望减少在完整 GC 中花费的平均时间。用 "XX:+UseParallelGC" 我们看到的是这样的:

[myhost ~]$ /usr/local/jdk7/bin/jstat -gcutil 9793 1000
  S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT
  0.00  49.57  95.93  93.32  99.48  10086  390.628   387 1005.334 1395.962
 56.99   0.00   7.42  93.32  99.48  10087  390.691   387 1005.334 1396.025
 56.99   0.00  22.19  93.32  99.49  10087  390.691   387 1005.334 1396.025
 56.99   0.00  36.28  93.32  99.49  10087  390.691   387 1005.334 1396.025
[myhost ~]$ ps -p 9793 -o etime=
 4-12:40:52

当我们切换到使用“-XX:+UseParNewGC -XX:+UseConcMarkSweepGC”时,我们会看到更多完整的 GC:

[myhost]$ /usr/local/jdk7/bin/jstat -gcutil 2514 1000
  S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT
  0.00 100.00 100.00  99.62  24.20    716   28.151    24   44.250   72.401
  0.00 100.00 100.00  99.62  24.20    716   28.151    24   44.250   72.401
  0.00 100.00 100.00  99.62  24.20    716   28.151    24   44.250   72.401
  0.00 100.00 100.00  99.62  24.20    716   28.151    24   44.250   72.401
  0.00 100.00 100.00  99.62  24.20    716   28.151    24   44.250   72.401
  0.00 100.00 100.00  99.62  24.20    716   28.151    24   44.250   72.401
  0.00 100.00 100.00  99.62  24.20    716   28.151    24   44.250   72.401
  0.00 100.00 100.00  99.62  24.20    716   28.151    24   44.250   72.401
  0.00 100.00 100.00  99.62  24.20    716   28.151    24   44.250   72.401
  0.00 100.00 100.00  99.62  24.19    716   28.151    24   44.250   72.401
  0.00 100.00 100.00  99.62  24.19    716   28.151    24   44.250   72.401
  0.00   0.00   5.92  99.44  24.19    716   28.151    24   56.361   84.512
100.00   0.00 100.00  99.66  24.19    718   28.221    26   56.417   84.638
100.00   0.00 100.00  99.66  24.19    718   28.221    26   56.417   84.638
100.00   0.00 100.00  99.66  24.19    718   28.221    26   56.417   84.638
100.00   0.00 100.00  99.66  24.19    718   28.221    26   56.417   84.638
100.00   0.00 100.00  99.66  24.19    718   28.221    26   56.417   84.638
100.00   0.00 100.00  99.66  24.19    718   28.221    26   56.417   84.638
100.00   0.00 100.00  99.66  24.19    718   28.221    26   56.417   84.638
100.00   0.00 100.00  99.66  24.19    718   28.221    26   56.417   84.638
100.00   0.00 100.00  99.66  24.19    718   28.221    26   56.417   84.638
100.00   0.00 100.00  99.66  24.19    718   28.221    26   56.417   84.638
100.00   0.00 100.00  99.66  24.19    718   28.221    26   56.417   84.638
100.00   0.00 100.00  99.66  24.19    718   28.221    26   56.417   84.638
100.00   0.00 100.00  99.66  24.19    718   28.221    26   56.417   84.638
100.00   0.00  34.98  99.87  24.20    720   28.319    27   68.708   97.026
100.00   0.00 100.00  99.87  24.20    721   28.319    28   68.708   97.026
100.00   0.00 100.00  99.87  24.20    721   28.319    28   68.708   97.026
100.00   0.00 100.00  99.87  24.20    721   28.319    28   68.708   97.026
100.00   0.00 100.00  99.87  24.20    721   28.319    28   68.708   97.026

这是我们的堆设置:

 -Xms256m -Xmx8192m -XX:PermSize=128m -XX:MaxPermSize=1024m

我们正在使用 JDK:

[myhost ~]$ /usr/local/jdk7/bin/java -XX:+PrintCommandLineFlags -version
-XX:InitialHeapSize=261346688 -XX:MaxHeapSize=4181547008 -XX:+PrintCommandLineFlags -XX:+UseCompressedOops -XX:+UseParallelGC
java version "1.7.0_80"
Java(TM) SE Runtime Environment (build 1.7.0_80-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode)

第一个实例有 4 天以上的正常运行时间。第二个实例只持续了几分钟。我们注意到它正在频繁地进行完整的 GC 并有很大的停顿,因此我们恢复了设置。

这里需要调整什么,以使 GC 统计数据不会偏离目标?

4

2 回答 2

0

在之前的捕获中,只有记录,但每个事件都有 1005 个完整的 GC 时间。在您的第二次捕获中,它显示了更多记录,但每个事件只有 44~68 个完整的 GC 时间。因此,如果您总结第一次和第二次捕获的完整 GC 时间,则更改配置后的第二次实际上具有更少的完整 GC 时间。

于 2016-10-18T20:26:38.330 回答
0

通过人体工程学,您可以提供参数,这些参数与默认的平台相关选择一起可以调整与应用程序属性相关的 GC 行为。更改收集器并没有指定调整如何影响执行的 GC 计数的事实并不能说明收集器选择是错误的,因为问题可能是由其他原因引起的。

就行为而言,ConcMarkSweepGC保证应用程序中的暂停时间更少,但在 GC 事件中生成任何东西。尽管您的第二个测试表明 Full GC 平均花费的时间有所改善,但您必须测试更长的时间才能了解收集器如何适应自身以满足指标。

根据最近的历史,并发收集器维护对在老年代耗尽之前剩余时间以及并发收集周期所需时间的估计。基于这些动态估计,将启动一个并发收集周期,目的是在老年代耗尽之前完成收集周期。

除此之外,您必须运行一些案例(包括测试其他收集器)才能在 GC 所花费的时间(收集器的承诺)和执行的 GC 事件之间取得适当的平衡,您可以在那里测试参数可以控制对象的提升方式(基于代际假设),或者在收集器运行之前可以接受的堆使用情况,例如:

-XX:NewRatio=<N>
-XX:CMSInitiatingOccupancyFraction=<N>
于 2016-10-18T21:04:03.677 回答