美文网首页
深入理解java虚拟机4——对象何时晋升到老年代

深入理解java虚拟机4——对象何时晋升到老年代

作者: 兮兮码字的地方 | 来源:发表于2021-08-25 19:17 被阅读0次

对象何时晋升到老年代?

1. 长期存活的对象进入老年代

在Minor gc中,把age大于设置的-XX:MaxTenuringThresholed值的对象晋升到老年代。

age是这样计算的,jvm为每个对象定义了一个对象年龄(Age)计数器,如果对象在Eden出生并经过第一次Minor GC后仍然存活,并能够被Survivor区容纳的话,将被移到Survivor区中,并且对象年龄设为1。

对象在Survivor区中每“熬过”一次Minor GC,年龄就加一岁。

2. 担保机制

当Survivor区的内存大小不足以装下一次Minor Gc中所有的存活对象的时候,就启动担保机制,将Survivor不够放的活对象,直接进入到老年代。

3. 大对象直接进入老年代

虚拟机提供了个-XX:pretenureSizeThreshold参数,令内存大于这个设置值的对象直接在老年代分配。这个参数只对Serial和ParNew收集器有效,Parallel Scavenge收集器不认识这个参数,一般它也不需要设置,如果遇到必须要设置这个参数的场合,可以考虑ParNew+CMS的收集器组合。

4. 动态对象年龄判断

错误的说法: 

如果在Survivor空间中相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代,无须等到MaxTenuringThreshold中要求的年龄。

正确的说法:

1. 不是某个年龄的对象总和,而是<=某个年龄的对象总和。

2.也不一定是大于SurVivor空间的一半,只是默认-XX:TargetSurvivorRatio设为50才是一半,应该是根据这个参数才对。

gc日志分析与调优:

要在gc日志中打印出每次新生代gc后,Survivor区中的对象的年龄分布。需要增加以下jvm参数:

-XX:+printTenuringDestribution

日志如下:

2021-08-25T18:52:44.064+0800: 1139.349: [GC (Allocation Failure) 2021-08-25T18:52:44.064+0800: 1139.350: [ParNew

Desired survivor size 53673984 bytes, new threshold 15 (max 15)

- age 1: 3622408 bytes, 3622408 total

- age 2: 387696 bytes, 4010104 total

- age 3: 743552 bytes, 4753656 total

- age 4: 2206184 bytes, 6959840 total

- age 5: 2300640 bytes, 9260480 total

: 850651K->13005K(943744K), 0.0127552 secs] 1112724K->275078K(1992320K), 0.0132327 secs] [Times: user=0.09 sys=0.00, real=0.01 secs]

Desired survivor size 53673984 bytes 代表期望占用Survivor 空间的53673984 字节;

new threshold 15 (max 15) 代表jvm动态计算的对象晋升年龄为15,  jvm设置的-XX:MaxTenuringThresholed对象晋升年龄为15;

jvm调优目的: 让total占用值(9260480) 大约为Desired Survivor期望值(53673984 ),即Survivor总大小的一半; 从而让gc尽可能发生在新生代, 这是为了尽量避免老年代的回收, 且任何晋升到老年代的对象都有可能造成垃圾碎片, 特别是过早晋升的。

相关文章

网友评论

      本文标题:深入理解java虚拟机4——对象何时晋升到老年代

      本文链接:https://www.haomeiwen.com/subject/bwjuvltx.html