JAVA内存分配及回收策略

虚拟机的内存分配规则及回收策略取决于使用的哪一种垃圾收集器,以及虚拟机中与内存相关参数的设定

1.对象优先在Eden分配

当Eden区内存不足时,虚拟机将发起一次Minor GC,并将之前存在于Eden区的对象转移到Survivor区,如果Survivor区内存不足,只是通过分配担保机制提前转移到老年代

—Xms,—Xmx:

设定初始及最大堆内存,当值一样时,堆内存不可扩展

—Xmn:

设置新生代内存大小

—XX:Survivor—Ratio:

设定新生代Eden区与一个Survivor区空间比例

新生代可用空间 = Eden区 + 一个Survivor区

—XX:+PrintGcDetails:

打印内存回收日志,并在进程结束时输出内存各区分配情况

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

容易导致内存有不少的空间时,提前触发垃圾收集。而复制对象时,又有高额的内存复制开销,所以直接进入老年代,避免在Eden区及两个Survivor区来回复制,产生大量内存复制操作

—XX:PretenureSizeThreshold:

设定大于该值的对象直接在老年代分配(只对Serial和ParNew两款新生代收集器有效)

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

虚拟机创建对象并设置对象头时,会存储一个对象年龄计数器,垃圾收集时计算分代年龄,当计算的值等于设定的年龄阈值时,对象将进入老年代

对象在Eden区诞生,经过第一次Minor GC后仍然存活,并且能被Survivor区容纳,对象移到Survivor区,分代年龄计为1,以后在Survivor区每熬过一次Minor GC,年龄就加1,直到增加到一定数量(默认15),就会晋升到老年代中

—XX:MaxTenuringThreshold:

设定进入老年代的对象年龄阈值

注:也不是一定要等到阈值中要求的年龄时才进入老年代

4. 动态对象年龄判定

如果在Survivor区中相同年龄所有对象大小的总和大于Survivor区空间的一半时,那么年龄大于等于该年龄的对象就可以直接进入老年代

5.空间分配担保

JDK 6 Update 24之前:

在年轻代发生Minor GC前,虚拟机检查老年代最大可用连续空间是否大于新生代所有对象总空间,若大于,那这次Minor GC可以确保安全。若不成立,则虚拟机根据—XX:HandlePromotionFailure参数设定值是否允许担保失败,若允许,则检查是否大于历次晋升到老年代对象的平均大小,如果大于,则进行

Minor GC(有风险,可能老年代空间不足分配新生代中的对象而被迫Full GC),如果小于或者设定不允许,那改为进行一次Full GC

JDK 6 Update 24之后:

XX:HandlePromotionFailure有这个参数,但不起作用,规则是只要老年代最大可用连续空间大于新生代所有对象总空间或者历次晋升的平均大小,就会Minor GC,否则Full GC

声明:本站部分文章内容及图片转载于互联 、内容不代表本站观点,如有内容涉及侵权,请您立即联系本站处理,非常感谢!

(0)
上一篇 2020年11月18日
下一篇 2020年11月19日

相关推荐