java虚拟机的内存分配策略

时间:2022-12-23 18:42:23


1,对象优先分配在Eden区

大多数情况下,对象在新生代Eden区中分配。当Eden区没有足够空间进行分配时,虚拟机执行一次Minor GC。

GC后剩下的对象如果无法放入Survivor区,通过分配担保进入老年代。

2,大对象直接进入老年代

大对象是指需要大量连续内存空间的对象。

可以通过设置-XX:PretenureSizeThreshold来决定超过多大的对象会直接进入老年代。

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

虚拟机为每一个对象都定义了一个对象年龄计数器。如果对象在Eden区出生并经过第一次Minor GC后仍然存活,并且能被Survivor区容纳的话,将被移动到Survivor区,同时对象年龄设为1.之后对象每经过一次Minor GC ,对象年龄加1。当对象年龄增加到一定值,便会晋升到老年代。

可以通过-XX:MaxTenuringThreshold参数设置进入老年代的年龄。

4,动态对象年龄判定

如果在Survivor区中相同年龄所以对象大小的总和大于Survivor的一半,年龄大于或等于该年龄的对象直接进入老年代,不需要等到XX:MaxTenuringThreshold要求的年龄。

5,空间分配担保

第一点说了分配担保的情况,但是前提是老年代本身得有容纳那些对象的空间,一共有多少对象存活下来再实际完成内存回收之前是无法明确知道的,所以只好取之前每一次回收晋升到老年代对象容量的平均值作为经验值,来决定是否进行Full GC来让老年代腾出更多空间。

取平均值的方法不是一个100%可用的方法,如果对象突增,远远高于平均值,就会导致担保失败。但是担保失败后还是会重新发起一次Full GC。