12

我启用了 gc 日志-XX:+PrintTenuringDistribution。但我对下面的任期分布感到很困惑。

从我读到的内容来看,第一个 gc 中的年龄 1(从 1 GC 中幸存)中有 10532656 个字节。在第二次 gc 中,年龄 2 中的 9178824 个字节(从 2 次 GC 中幸存下来)。这很好,因为有些对象在第一次和第二次 GC 之间死亡。

但是在第二次 GC 中,16101552 字节在年龄 3 中,而在第一次 GC 中只有 14082976 字节在年龄 2 中。我不明白为什么这个数字会增加。年龄 n 中的所有字节不应该来自上一次 GC 中的年龄 n-1 吗?还是我误解了这些数字?

谢谢。

2013-10-19T19:46:30.244+0800: 169797.045: [GC2013-10-19T19:46:30.244+0800: 169797.045: [ParNew
Desired survivor size 87359488 bytes, new threshold 4 (max 4)
- age   1:   10532656 bytes,   10532656 total
- age   2:   14082976 bytes,   24615632 total
- age   3:   15155296 bytes,   39770928 total
- age   4:   13938272 bytes,   53709200 total
: 758515K->76697K(853376K), 0.0748620 secs] 4693076K->4021899K(6120832K), 0.0756370 secs] [Times: user=0.42 sys=0.00, real=0.07 secs]
2013-10-19T19:47:10.909+0800: 169837.710: [GC2013-10-19T19:47:10.909+0800: 169837.711: [ParNew
Desired survivor size 87359488 bytes, new threshold 4 (max 4)
- age   1:    9167144 bytes,    9167144 total
- age   2:    9178824 bytes,   18345968 total
- age   3:   16101552 bytes,   34447520 total
- age   4:   21369776 bytes,   55817296 total
: 759449K->63442K(853376K), 0.0776450 secs] 4704651K->4020310K(6120832K), 0.0783500 secs] [Times: user=0.43 sys=0.00, real=0.07 secs]

编辑:

由于声明对象的竞争条件,这已被确认为 jvm 本身的错误。

详细讨论可以在这里找到:

http://mail.openjdk.java.net/pipermail/hotspot-gc-use/2013-October/001635.html

4

2 回答 2

5

对 OpenJDK 邮件列表 (hotspot-gc-use@openjdk.java.net) 的讨论表明,这种异常的使用期限分布报告是由于每个年龄计数器未注明日期的线程之间的竞争条件造成的。

错误JDK-8027363已被填补。

错误摘录:

这是问题所在:在将目标对象复制到幸存者空间或旧代的代码中,多个线程可能会争相声明一个对象。在对象的年龄低于tenuring阈值的情况下,或者如果老一代不是CMS,我们将首先复制该对象,然后通过交换指向该副本的转发指针来声明该对象。其他副本被丢弃,获胜线程继续。问题是年龄表是由所有竞相进行复制的线程递增的。解决方法是只有比赛的获胜者应该增加年龄表以避免多次增加。

于 2013-10-31T02:02:57.930 回答
2

您正在阅读日志,问题在于您在 4 中指定的任期阈值。

The GC parameter “-XX:MaxTenuringThreshold” defines how many minor GC cycles 
an object can stay in the survivor spaces until it finally gets tenured to the 
old space.

因此,您从一个清除到下一个清除累积了字节,因为您可以根据您配置的使用期限阈值,在多个 GC 轮次中将内存置于特定年龄。

例如,如果您想查看您希望看到的特定行为,请将阈值设置为 on 0

-XX:MaxTenuringThreshold=0—Makes the full NewSize available to every NewGC cycle, 
and reduces the pause time by not evaluating tenured objects. Technically, 
this setting promotes all live objects to the older generation, rather 
than copying them
于 2013-10-24T13:28:39.497 回答