Java老年代持续增长 - 需要帮助解释Java GC输出

9
我在一款性能关键的Java服务器端应用程序上工作。
系统启动后,我希望不会创建长期存在的对象,只会创建短暂的对象(最多10秒)。因此,我想调整JVM,使旧生代在系统启动后保持恒定。
我认为我已经成功了,但我不明白为什么(见下文)。
以下是我们的设置:
-Xmx3000m -Xms3000m -verbose:gc -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -XX:+UseConcMarkSweepGC -XX:SurvivorRatio=5 -XX:TargetSurvivorRatio=90 -XX:MaxTenuringThreshold=31 -XX:+PrintTenuringDistribution -XX:NewSize=1250m -XX:MaxNewSize=1250m
我们使用Oracle的Java 1.6版本。
我对 "PrintTenuringDistribution" 标志的输出非常困惑。我看到类似以下的输出:
893.866: [GC 893.866: [ParNew
Desired survivor size 168512712 bytes, new threshold 16 (max 31)
- age   1:   13251072 bytes,   13251072 total
- age   2:    1135456 bytes,   14386528 total
- age   3:      59104 bytes,   14445632 total
- age   4:     467384 bytes,   14913016 total
- age   5:      68688 bytes,   14981704 total
- age   6:      43336 bytes,   15025040 total
- age   7:      41344 bytes,   15066384 total
- age   8:       6872 bytes,   15073256 total
- age   9:      87568 bytes,   15160824 total
- age  10:      23840 bytes,   15184664 total
- age  11:      99712 bytes,   15284376 total
- age  12:       5224 bytes,   15289600 total
- age  13:       1000 bytes,   15290600 total
- age  14:      59056 bytes,   15349656 total
- age  15:   65225584 bytes,   80575240 total
: 1015468K->95478K(1097152K), 0.0268070 secs] 1387738K->467748K(2889152K), 0.0269910 secs] [Times: user=0.31 sys=0.00, real=0.03 secs]
899.179: [GC 899.180: [ParNew
Desired survivor size 168512712 bytes, new threshold 16 (max 31)
- age   1:   12438336 bytes,   12438336 total
- age   2:    1531984 bytes,   13970320 total
- age   3:      87920 bytes,   14058240 total
- age   4:      58824 bytes,   14117064 total
- age   5:     463368 bytes,   14580432 total
- age   6:      68688 bytes,   14649120 total
- age   7:      43336 bytes,   14692456 total
- age   8:      40136 bytes,   14732592 total
- age   9:       6872 bytes,   14739464 total
- age  10:      87568 bytes,   14827032 total
- age  11:      23840 bytes,   14850872 total
- age  12:      99712 bytes,   14950584 total
- age  13:       2896 bytes,   14953480 total
- age  14:       1000 bytes,   14954480 total
- age  15:   65282456 bytes,   80236936 total
: 1009782K->98799K(1097152K), 0.0383370 secs] 1382052K->471069K(2889152K), 0.0385490 secs] [Times: user=0.36 sys=0.00, real=0.03 secs]

假设我有很多age=15的对象,阈值为16,我期望每个GC中的对象要么(a)晋升到老年代,要么(b)被垃圾回收。

但是根据JConsole,我的老年代没有增长。那么所有这些对象都发生了什么?


你应该执行堆转储并将其发送给客户进行分析 :) - Chris Dennett
从日志来看,最大 tenuring 年龄为 31。 - rohitmohta
1个回答

1

你所拥有的年龄是幸存者空间中的对象年龄。由于你拥有一个较大的伊甸园空间,大部分进入幸存者空间的对象都会相对较老。


谢谢Peter。不过我还是有点困惑。看着我问题中包含的第一个GC,我可以看到65225584字节的对象年龄为15。到第二次GC发生时,这些对象肯定已经年龄为16了,所以应该被提升到老年代了吧? - Phil Harvey
我认为只有在生存者空间不足时,生存者才会被推入旧世代。您的生存者空间似乎每个为178 MB(1250 /(5 + 1 + 1))。 - Peter Lawrey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接