1

我正在尝试减少 GC 暂停(约 400 毫秒)的问题。我注意到我总是让一名工人比其他工人慢得多:

2013-06-03T17:24:51.606+0200: 605364.503: [GC pause (mixed)
Desired survivor size 109051904 bytes, new threshold 1 (max 1)
- age   1:   47105856 bytes,   47105856 total
, 0.47251300 secs]
[Parallel Time: 458.8 ms]
  [GC Worker Start (ms):  605364503.9  605364503.9  605364503.9  605364503.9  605364503.9  605364504.0
   Avg: 605364503.9, Min: 605364503.9, Max: 605364504.0, Diff:   0.1]
-->  [**Ext Root Scanning (ms)**:  **356.4**  3.1  3.7  3.6  3.2  3.0
   Avg:  62.2, **Min:   3.0, Max: 356.4, Diff: 353.4**] <---
  [Update RS (ms):  0.0  22.4  33.6  21.8  22.3  22.3
   Avg:  20.4, Min:   0.0, 

如您所见,一名工人用了 356 毫秒,而其他工人只用了 3 毫秒!!!

如果有人有想法或认为这很正常..

4

1 回答 1

2

[我宁愿将此作为评论发布,但我仍然缺乏这样做的必要要点]

不知道是否正常,但我遇到了同样的问题:

2014-01-16T13:52:56.433+0100: 59577.871: [GC pause (young), 2.55099911 secs]
   [Parallel Time: 2486.5 ms]
      [GC Worker Start (ms):  59577871.3  59577871.4  59577871.4  59577871.4  59577871.4  59577871.5  59577871.5  59577871.5
       Avg: 59577871.4, Min: 59577871.3, Max: 59577871.5, Diff:   0.2]
      [Ext Root Scanning (ms):  152.0  164.5  159.0  183.7  1807.0  117.4  113.8  138.2
       Avg: 354.5, Min: 113.8, Max: 1807.0, Diff: 1693.2]

我一直无法找到关于这个主题的很多信息,但在这里http://mail.openjdk.java.net/pipermail/hotspot-gc-use/2013-February/001484.html

基本上,正如您推测的那样,在处理单个根时,GC 工作线程被阻止了。我已经看到了由填充代码缓存(保存 JIT 编译方法的地方)引起的类似问题。代码缓存被视为单个根,因此由单个 GC 工作线程完整声明。随着代码缓存被填满,声称要扫描代码缓存的线程开始被阻塞。

完整的 GC 解决了这个问题,因为这是 G1 当前进行类卸载的地方:完整的 GC 卸载了一大堆类,允许 nmethod 清除程序释放任何已卸载类的方法的任何编译代码。所以在一次完整的 GC 之后,代码缓存中已编译方法的数量会减少。

它也可能只是加载类的绝对数量,因为系统字典也被视为单个可声明的根。

我想我会尝试启用代码缓存刷新并让您知道。如果您最终设法解决了这个问题,请告诉我,我也在努力完成它。

亲切的问候

于 2014-01-19T16:37:58.643 回答