java 内存分配策略

1 对象优先在新生代Eden区中进行分配,当Eden区没有足够空间进行分配时,虚拟机进行一次Minor GC

2 大对象直接进入老年代
所谓大对象就是需要大量连续内存空间的java对象,最典型的大对象就是很长的字符串以及数组。

3 长期存活的对象进入老年代
虚拟机为每个对象定义了对象年龄的计数器,如果对象在Eden区出生,并经过第一次Minor GC后仍然存活,并且能够被Survivor容纳的化,将被移动到Survivor空间中,并且对象的年龄设置为1。对象每经过一次Minor GC,年龄就增加1岁,当它的年辆增到一定程度(默认是15岁),就将会被晋升到老年代中。

4 动态对象年龄判定
虚拟机并不是永运要求对象的年龄必须达到MaxTenuringThreshold才能晋升老年代,如果在Survivor空间中相同年龄的所有对象的大小总和大于Survivor空间的一半,年龄大于或者等于该年龄的对象就可以直接进入老年代。

5 空间分配担保:
新生代使用的复制算法,新生代分为Eden区和两个Survivor, Eden区和一个 Survivor
的大小比例默认是8:1. 新生代进行垃圾回收也就是Minor GC的时候,有可能Survivor空间的大小无法存放所有存活的对象,那么就需要将新的空间来存放多余的对象,这部分空间由老年代来贡献,此时也要保证老年代的剩余连续的空间是足够用的。也就是由老年代来担保此次Minor GC是安全的。条件就是老年代的最大可用的连续空间是否大于新生代所有的空间,如果这个这件成立,那么担保就是成立,Minor GC 就是安全的。

如果不成立,虚拟机会查看 HandlePromotionFailure设置值是否允许担保失败。如果允许,那么会继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小,如果大于,将尝试进行一次Minor GC。如果小于,那么虚拟机就会改为进行一次Full GC,当不允许担保失败时也会进行一次Full GC。

老年代最大可用连续空间大于历次晋升到老年代对象的平均大小时,进行Minor GC,也可能失败,因为本次的晋升到老年代的对象的数量是不确定的,很有可能大于之前的平均值。如果Minor GC失败,那么虚拟机只好重新进行Full GC。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章