Java 为什么对象的大小与年龄n+;当前suvivor中的1比上一个suvivor中年龄为n的对象大?
在尝试优化JVM GC标志时,我添加了Java 为什么对象的大小与年龄n+;当前suvivor中的1比上一个suvivor中年龄为n的对象大?,java,garbage-collection,jvm,jvm-hotspot,Java,Garbage Collection,Jvm,Jvm Hotspot,在尝试优化JVM GC标志时,我添加了-XX:+PrintTenuringDistribution来打印不同年龄段的对象大小分布,我发现了一个奇怪的现象 直观地说,当前GC进程中年龄为(n+1)的对象的大小应该小于上一个GC进程中年龄为n的对象的大小 第二个GC中年龄为2的对象是第一个GC中年龄为1的对象。假设第一个GC中年龄为1的活动对象的大小为S11,第二个GC中年龄为2的活动对象的大小为S22。然后S11>S22,因为一些1岁的物体会被破坏 但我看到的是: - age 1: 50
-XX:+PrintTenuringDistribution
来打印不同年龄段的对象大小分布,我发现了一个奇怪的现象
直观地说,当前GC进程中年龄为(n+1)的对象的大小应该小于上一个GC进程中年龄为n的对象的大小
第二个GC中年龄为2的对象是第一个GC中年龄为1的对象。假设第一个GC中年龄为1的活动对象的大小为S11,第二个GC中年龄为2的活动对象的大小为S22。然后S11>S22,因为一些1岁的物体会被破坏 但我看到的是:
- age 1: 5028488 bytes, 5028488 total
gc happened...
- age 2: 5030440 bytes, 7630688 total
gc happened...
- age 3: 6864328 bytes, 10406920 total
gc happened...
- age 4: 13155416 bytes, 17153720 total
gc happened...
- age 5: 11057632 bytes, 15633880 total
gc happened...
- age 6: 17349112 bytes, 22898584 total
正如我们看到的,它的大小增加了。我不知道为什么会这样。以下是完整的GC日志:
2017-08-30T13:22:33.821+0800: 219271.297: [GC (Allocation Failure)
2017-08-30T13:22:33.821+0800: 219271.297: [ParNew Desired survivor size 85557248 bytes, new threshold 6 (max 6)
- age 1: 5028488 bytes, 5028488 total
- age 2: 394616 bytes, 5423104 total
- age 3: 414024 bytes, 5837128 total
- age 4: 851040 bytes, 6688168 total
- age 5: 462728 bytes, 7150896 total
- age 6: 526064 bytes, 7676960 total
: 1343960K->9188K(1504064K), 0.0105175 secs] 5697641K->4363292K(8221504K), 0.0106539 secs] [Times: user=0.11 sys=0.01, real=0.01 secs]
2017-08-30T13:22:33.831+0800: 219271.308: Total time for which application threads were stopped: 0.0119211 seconds, Stopping threads took: 0.0001500 seconds
2017-08-30T13:22:34.486+0800: 219271.963: [GC (Allocation Failure) 2017-08-30T13:22:34.486+0800: 219271.963: [ParNew Desired survivor size 85557248 bytes, new threshold 6 (max 6)
- age 1: 2600248 bytes, 2600248 total
- age 2: 5030440 bytes, 7630688 total
- age 3: 392760 bytes, 8023448 total
- age 4: 413704 bytes, 8437152 total
- age 5: 850888 bytes, 9288040 total
- age 6: 462488 bytes, 9750528 total
: 1346148K->11226K(1504064K), 0.0103425 secs] 5700252K->4365843K(8221504K), 0.0104998 secs] [Times: user=0.11 sys=0.01, real=0.01 secs]
2017-08-30T13:22:34.497+0800: 219271.973: Total time for which application threads were stopped: 0.0116511 seconds, Stopping threads took: 0.0000986 seconds
2017-08-30T13:22:35.151+0800: 219272.627: [GC (Allocation Failure) 2017-08-30T13:22:35.151+0800: 219272.627: [ParNew Desired survivor size 85557248 bytes, new threshold 6 (max 6)
- age 1: 3132664 bytes, 3132664 total
- age 2: 409928 bytes, 3542592 total
- age 3: 6864328 bytes, 10406920 total
- age 4: 392304 bytes, 10799224 total
- age 5: 413120 bytes, 11212344 total
- age 6: 588304 bytes, 11800648 total
: 1348186K->12885K(1504064K), 0.0109247 secs] 5702803K->4367954K(8221504K), 0.0110585 secs] [Times: user=0.11 sys=0.02, real=0.01 secs]
2017-08-30T13:22:35.162+0800: 219272.638: Total time for which application threads were stopped: 0.0122836 seconds, Stopping threads took: 0.0001519 seconds
2017-08-30T13:22:35.841+0800: 219273.318: [GC (Allocation Failure) 2017-08-30T13:22:35.841+0800: 219273.318: [ParNew Desired survivor size 85557248 bytes, new threshold 6 (max 6)
- age 1: 2544776 bytes, 2544776 total
- age 2: 1045056 bytes, 3589832 total
- age 3: 408472 bytes, 3998304 total
- age 4: 13155416 bytes, 17153720 total
- age 5: 392008 bytes, 17545728 total
- age 6: 412920 bytes, 17958648 total
: 1349845K->19062K(1504064K), 0.0100055 secs] 5704914K->4374704K(8221504K), 0.0101450 secs] [Times: user=0.10 sys=0.02, real=0.01 secs]
2017-08-30T13:22:35.851+0800: 219273.328: Total time for which application threads were stopped: 0.0113139 seconds, Stopping threads took: 0.0001079 seconds
2017-08-30T13:22:36.260+0800: 219273.736: Total time for which application threads were stopped: 0.0018019 seconds, Stopping threads took: 0.0003786 seconds
2017-08-30T13:22:36.521+0800: 219273.997: [GC (Allocation Failure) 2017-08-30T13:22:36.521+0800: 219273.997: [ParNew Desired survivor size 85557248 bytes, new threshold 6 (max 6)
- age 1: 2977976 bytes, 2977976 total
- age 2: 408656 bytes, 3386632 total
- age 3: 781704 bytes, 4168336 total
- age 4: 407912 bytes, 4576248 total
- age 5: 11057632 bytes, 15633880 total
- age 6: 391592 bytes, 16025472 total
: 1355810K->16950K(1504064K), 0.0107807 secs] 5711453K->4372995K(8221504K), 0.0109248 secs] [Times: user=0.11 sys=0.02, real=0.01 secs]
2017-08-30T13:22:36.532+0800: 219274.008: Total time for which application threads were stopped: 0.0121995 seconds, Stopping threads took: 0.0001272 seconds
2017-08-30T13:22:37.214+0800: 219274.691: [GC (Allocation Failure) 2017-08-30T13:22:37.214+0800: 219274.691: [ParNew Desired survivor size 85557248 bytes, new threshold 6 (max 6)
- age 1: 3480256 bytes, 3480256 total
- age 2: 473344 bytes, 3953600 total
- age 3: 407336 bytes, 4360936 total
- age 4: 781080 bytes, 5142016 total
- age 5: 407456 bytes, 5549472 total
- age 6: 17349112 bytes, 22898584 total
公式Size(年龄(n+1))
是错误的
以上面的gc.log
为例,在第一个gc中,大小(年龄(1))
是5028488
,但在第二个gc中,大小(年龄(1))
是2600248
,这意味着对象生成速度比开始时要慢
因此,您将看到,在第二个gc中,大小(年龄(2)
)是5030440
,几乎等于第一个gc中的大小(年龄(1))
,这使得它大于第二个gc中的大小(年龄(1))
关键是生成速度是不断变化的。所以可能是Size(年龄(n+1))
,或者可能是Size(年龄(n+1))>Size(年龄(n))
,这都是可能的
希望我没有误解您的问题。解决方案是仔细查看日志。您的输出显示为新的所需幸存者大小85557248字节,但查看上一个日志,您会看到组合空间消耗为22898584字节。这比幸存者能承受的更大。因此,基本上,您的年龄统计必须同时参考
幸存者
和终身
我假设,您有一些年龄为2/3/4/5/6的对象,这些对象已升级为
终身
,并且不受发生的集合的影响。第二次GC中年龄为2的对象是第一次GC中年龄为1的对象。假设第一个GC中年龄为1的活动对象的大小为S11,第二个GC中年龄为2的活动对象的大小为S22。然后S11>S22,因为一些年龄为1的对象被销毁。在第一次GC和第二次GC之间生成的那些对象的年龄应该是1,而不是2。难道这些对象不是越来越多而是在增长吗?比如说,一个具有引用的对象,在第一次收集期间为null
,但在下一次迭代期间变为引用实际对象?在下一次迭代期间引用的新对象有其自身的年龄