简明内存分配策略

对象优先在Eden分配。当Eden区没有足够空间分配时,虚拟机将发起一次Minor GC

Minor GC 和 Full GC是啥意思

新生代GC(Minor): 指发生在新生代的垃圾收集动作,因为Java对象大多都具有朝生夕死的特性,所以Minor GC非常频繁,一般回收速度比较快。

老年代GC(Major GC/Full GC):指发生在老年代的GC,出现Major GC,通常会伴随至少一次的Minor GC。Major GC的速度一般会比Minor GC慢10倍以上。

大对象直接进入老年代

所谓大对象指,需要大量连续内存空间的JAVA对象,最典型的大对象就是那种很长的字符串及数组。大对象以内存分配来说是一个坏消息。经常出现大对象容易导致内存还有不少空间时,提前触发垃圾回收,以此得到足够的连续空间。
参数 -XX:PretenureSizeThreahold 指大于些设置的对象直接进入老年代。

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

说对象内存布局时,提到了对象头里有对象的分代年龄。对象出生在Enden区,经过第一次Minor GC后,仍存活且Survivor能容纳,对象年龄就设置为1。之后,每经历一次Minor GC,对象年龄就增加1。当年龄增加到一定程度(默认15岁),该对象就进入老年代。参数 -XX:MaxTenuring Threshold设定此阈值。

对象提前进入老年代的情景:如果Survivor空间中相同年龄的所有对象大小之和,比Survivor的一半还大,那该年龄,以及大于该年龄的对象直接进入老年代。

空间分配担保

在发生Minor GC之前,虚拟机会检查老年代最大可用连续空间是否大于新生代所有对象总和,如果条件成立,那Minor GC可以确保是安全的。如果不成立,则查看HandlePromotionFailure设置值是否允许担保失败。如果允许,那会继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象平均大小 ,如果大于,则尝试进行一次Minor GC。如果是小于,或HandlePromotionFailure设置为不允许,则时行一次Full GC。

上面说的取平均值进行比较其实仍然是一种动态概率的手段,是有可能出现担保失败。如果出现了担保失败,那只好在失败之后重新发起一次Full GC。为避免Full GC过于频繁,多数情况下,将HandlePromotionFailure开关打开。

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