JVM的几种内存分配策略

1. 对象优先在Eden分配。

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

PS:

新生代GC(Minor GC):发生在新生代的GC,Java独享大多都是朝生夕灭,因此Minor GC非常频繁,回收速度也快;

老年代GC(Major GC / Full GC):发生在老年代的GC,速度比Minor GC慢10倍以上。

2. 大对象直接进入老年代。

大对象是指需要大量连续空间的Java对象,如很长的字符串以及数组。经常出现大对象容易导致内存还有不少空间就提前触发GC以获取足够连续空间来安置他们。

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

虚拟机回收时必须能识别哪些对象放在新生代,哪些放在老年代,才能采用分代收集的思想。虚拟机给每个对象定义了一个对象年龄计数器,如果对象在Eden出生并经过第一次Minor GC后仍然存活,并且能被Survivor容纳,将被移动到Survivor空间中,并且对象年龄设为1。对象在Survivor中每熬过一次Minor GC,年龄加1,当年龄增加到一定程度(默认为15岁,此参数可以调整),就会晋升到老年代中。

4. 动态对象年龄判定。

虚拟机并不是永远要求对象的年龄必须到某个值才能晋升老年代,如果在Survivor中相同年龄的所有对象大小总和大于Survivor空间的一半,年龄大于等于该年龄的对象就可以直接进入老年代。

5. 空间分配担保。

在发送Minor GC之前,虚拟机会先检查老年代最大可用的连续空间是否大于新生代所有对象总空间,如果该条件成立,则可以确保Minor GC时发生100%的对象都存活这种极端情况下,可以把这些存活对象全部转移到老年代中,那么此时Minor GC是安全的。如果条件不成立,则虚拟机查看是否允许担保失败,如果允许,那么继续检查老年代最大可用的连续空间是否大于每次回收晋升到老年代对象的平均大小,如果大于,将尝试一次Minor GC;如果小于(或者设置不允许担保失败),那么改为进行一次Full GC。

扫描二维码关注公众号,回复: 245321 查看本文章

猜你喜欢

转载自my.oschina.net/u/3342874/blog/1801560