内存分配与回收策略

来源:互联网 发布:数据库怎么定义主键 编辑:程序博客网 时间:2024/05/21 03:28

对象优先分配在Eden上

大多数情况下,对象在新生代的Eden上分配。当Eden区没有足够空间进行分配时,虚拟机将发起一次Minor GC(新生代垃圾收集)。

大对象分配

大对象一般直接进入老年代,所谓大对象是指,需要大量连续内存空间的Java对象,最典型的就是很长的字符串和数组,大对象对内存分配来说是一个坏消息,应尽量避免。

长期存活的对象

既然虚拟机采用了分代收集的思想,那么内存回收时必须能识别哪些对象应该放在新生代,哪些应该放在老年代。因此虚拟机给每个对象定义了一个对象年龄(Age)计数器,如果对象在Eden中出生并经历过一次Minor GC后仍然存活,并且能被Survivor容纳的话,将被移动到Survivor中,对象年龄被设为1。在Survivor中每熬过一次Minor GC,年龄就增加1岁,当增加到一定程度(默认15岁,用户可调)时移入老年代中。

动态对象的年龄

如果在Survivor中相同年龄所有对象大小的综合大于Survivor空间的一般,年龄大于或等于此年龄的对象可以直接进入老年代。此举是为了适应不同程序的内存状况。

空间分配担保

发生Minor GC之前,虚拟机会先检查老年代最大可用的连续空间是否大于新生代所有对象总空间,如果成立,则Minor GC是确保安全的。如果不成立,则虚拟机会查看HandlePromotionFailure设置值是否允许担保失败。如果允许,那么继续检查老年代最大可用连续空间是否大于历次晋升到老年代对象的平均大小,如果大于,尝试进行一次Minor GC,尽管这次是有风险的;如果小于,或者HandlePromotionFailure设置不允许冒险,此时改为进行一次Full GC。
这里的取平均值进行比较其实仍然是一种动态概率的手段,所以会比较冒险。

原创粉丝点击