java中自动化内存管理的自动分为两类:
- 为对象分配内存
- 回收分配给对象的内存
对象分配的几个原则:
-
对象优先在新生代Eden分配
-
大对象直接进入老年代
虚拟机提供-XX:PretenureSizeThreshold参数,令大于这个设置值的对象直接在老年代分配。
这样做的目的:防止在Eden区及两个Survivor区之间发生大量的内存赋值(新生代采用复制算法手机内存)
-
长期存活的对象进入老年代
jvm为每个对象定义了一个对象年龄计数器,对象在Survivor区中每经过一次Minor GC,年龄就增加1,默认增加到15,就会晋升到老年代,可通过设置-XX:MaxTenuringThreshold设置
-
动态年龄判定进入老年代
对普通对象而言,并非一定要通过年龄晋升到老年代,当Survivor空间中相同年龄所有对象大小的总和大于Srvivor空间的一半,年龄大于等于该年龄的对象就直接进入老年代
空间分配担保机制
发生Minor GC前,jvm会先检查老年代最大可用的连续空间是否大于新生代所有对象总空间——是,则Minor GC认为是安全的;否则jvm会查看HandlePromotionFailure设置值是否允许担保失败,若允许,则检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小(概率),若小于或者不允许,将进行一次Full GC。
- 为何说是担保?
因为新生代使用的复制算法,而且只要一个Survivor作为轮换备份,考虑极端情况,Eden区和Survivor0全部对象都存活,Survivor容纳不下,此时就需要将Survivor区无法容纳的对象直接进入老年代(但不是全部对象进入);
而前面的取平均大小其实是个概率论,因而说是冒险
进入老年代的3种方式
- 大对象
- 年龄计数器
- 动态年龄
网友评论