MaxTenuringThreshold该参数用于控制对象经过GC多少次仍然存活后晋升到老年代的最大阈值,参数最大可配置为15,即对象最多经过15次GC后仍然存活就会晋升到老年代
记住!是最大!也就是说实际上不一定会经过15次才能晋升!这个值的JVM内部会进行动态计算然后动态改变的。
最近在线上有个应用GC非常频繁,MaxTenuringThreshold参数配置的是15,而以前对这个参数的理解是一定要经过15次后才会晋升,所以导致整个排查过程根本就不对,线上日志如下:
Desired survivor size 184549376 bytes, new threshold 1 (max 15)
- age 1: 369096960 bytes, 369096960 total
....下面进行GC,年轻代有很多对象全跑到了老年代
当时思考方向是:age为1,离15有很大的距离,不应该会晋升,老年代空间增加是因为大对象
这个思考方向真是大错特错了,因为对MaxTenuringThreshold理解错了。注意日志中有几个关键字
new threshold 1 (max 15)
意思是说阈值现在变成了1,而不是15!所以直接就晋升了!那么为什么会变成1呢,这个动态计算的算法是怎么样的,参考了一下一些大神的文章再看了下源码,终于发现原因所在,直接看源码会比较清晰,源码如下:
int ageTable::compute_tenuring_threshold(size_t survivor_capacity) {
//TargetSurvivorRatio默认为50
//d