JVM(八)堆内存分配策略

我们都知道,java中对象都放在堆中,那么JVM会如何给新生对象分配内存呢?

内存参数回顾:-Xms初始堆内存大小,-Xmx最大堆内存,相等不可扩展,-Xmn堆中新生代对象的内存大小,剩余的就是老年代内存

有下面几个原则:

(1)优先使用Eden区域

新来的要分配内存的对象都属于新生代对象,我们知道,回收新生代对象是复制算法,,分为Eden区和两个survivor区,所以新生代对象首先在Eden中分配,当Eden内存不够,发起一次Minor GC(新生代GC),如果Minor GC执行完,还不够,就需要老年代区域担保分配,这里是把已经在的对象转移到老年代,要分配的新对象还是在会存在Eden

(2)大对象直接放入老年代

虚拟机提供参数-XX:PretenureSizeThreshold参数(这个参数只在serial和ParNew起作用),当对象比这个值大,就直接存入老年代

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

虚拟机为每个新生对象设置一个年龄,当进行一次Minor GC时,会有对象被移到survivor2中,在survivor2中的对象没熬过一次Minor GC,年纪就会增加,直到超过参数-XX:MaxTenuringThreshold设置的阈值就会被移到老年代,这个阈值默认是15。

(4)动态判断对象年龄

并不是只有到了这个年纪对象的阈值才会被移到老年代,当survivor2中相同年纪的对象总数大于survivor2空间的一般,大于这个年纪和等于这个面积的对象都会被移到老年代中

(5)空间分配担保

前面说到了空间担保是指需要老年代担保,那么你必须判断,老年代中目前连续的内存空间是否大于当前survivor2中所有对象的大小,大于才能担保

所以在每一次Minor GC之前都会检查,如果大于则Minor GC认为是安全的。在jdk1.6之后,如果检查安全就进行Minor GC,否则进行full GC.。那么1.5之前是检查参数是否允许担保失败

猜你喜欢

转载自blog.csdn.net/wangdongli_1993/article/details/81188055