虚拟机内存分配与回收策略(十二)

在经典分代的设计下,新生对象通常会分配在新生代中,少数情况(对象大小超过阈值)也可能直接分配在老年代。

对象优先在Eden分配

多数情况,对象会在新生代Eden区分配,当Eden区没有足够的空间时虚拟机会发起一次Minor GC。
-XX:+PrintGCDetails,告诉虚拟机发生垃圾回收的时打印内存回收日志,并且在进程退出的时候输出当前内存各区域分配情况。
-XX:SurvivorRatio=8决定了新生代Eden区与一个Survivor区的空间比为8:1。
例:
当新生代中Eden区为8M时两个Survivor区都为1M。
假设新生代为10M(可用空间为9M=8M的Eden区和一个1M的Survivor区),老年代为10M,当3个大小为2M的对象分配到Eden区后,如果在分配一个大小为4M的对象时,因为新生代空间不足,所有发生Minor GC,但是虚拟机发现剩余的1MSurvivor区不足以存放6M的对象,所以只好将初始的三个对象通过分配担保机制提前转移到老年区。

大对象直接进入老年区

虚拟机参数:-XX:PretenureSizeThreshold,指定大于该设置的对象直接在老年区分配。
目的:避免在Eden区和两个Survivor区之间来回复制,产生大量的内存复制操作。

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

虚拟机在对象头中为每个对象定义了一个对象年龄计数器,如果对象在Eden区诞生,经过一个Minor GC后仍存活,并能被Survivor区存储,该对象会被移至Survivor区并且Age加一。它的年龄增加到一定程度就会晋升到老年区,默认为15。
虚拟机参数:-XX:MaxTenuringThreshold 设置的值为对象在新生区的年龄阈值。

动态对象年龄判定

HotSpot虚拟机并不是永远要求新生区的对象年龄到达阈值后进入老年区,如果在Survivor空间中相同年龄的所有对象的大小总和大于Survivor区空间的一半,年龄大于等于该对象的所有对象就可以直接进入老年代。

空间分配担保

在发生Minor GC之前,虚拟机必须要检查老年代最大可用的连续空间是否大于新生区所有对象的总空间,如果条件成立,那么这一次Minor GC可以确保是安全的,如果不成立,则虚拟机会先查看-XX:HandlePromotionFailure参数的设置值是否允许担保失败;如果允许,检查老年代最大连续可用空间是否大于历次晋升到老年代对象的平均大小 ,如果大于就进行一次Minor GC(也有风险,可能本次晋升的空间大于历次的平均),如果小于,或者不允许担保风险,这是就要改为进行一次FULL GC。

猜你喜欢

转载自blog.csdn.net/weixin_43663421/article/details/109320326
今日推荐