内存分配与回收策略算法
1.对象优先在Eden分配安全
大多数状况下,对象在新生代Eden区中分配。当Eden区没有足够空间进行分配时,虚拟机将发起一次Minor GC。ide
-XX:+PrintGCDetails:在发生垃圾收集行为时打印内存回收日志,而且在进程退出的时候输出当前的内存各区域分配状况。spa
-XX:SurvivorRatio=8决定了新生代中Eden区与一个Survivor区的空间比例是8:1。日志
新生代GC(Minor GC):发生在新生代的垃圾收集动做,由于Java对象大多都具有朝生夕灭的特性,因此Minor GC很是频繁,通常回收速度也很是快。对象
老年代GC(Major GC/Full GC):指发生在老年代的GC,出现了Major GC常常会伴随至少一次Minor GC(非绝对,在Parallel Scavenge收集器的收集策略就有直接进行Major GC的策略选择过程)。Major GC速度通常会比Minor GC慢10倍以上。进程
2.大对象直接进入老年代内存
大对象:须要大量连续内存空间的Java对象,虚拟机
-XX:PretenureSizeThreshold:令大于这个设置值的对象直接在老年代分配。目的是避免在Eden区及两个Survivor区直接发生大量的内存复制(新生代采用复制算法收集内存)。该参数只对Serial和ParNew两款收集器有效。it
3.长期存活的对象将进入老年代
为了在内存回收时能区别哪些对象应放在新生代,哪些对象应放在老年代中,虚拟机给每一个对象定义了一个对象年龄(Age)计数器。
若是对象在Eden出生并通过第一次Minor GC后仍然存活,而且能被Survivor容纳的话,将被移动到Survivor空间中,而且对象年龄设为1。对象在Survivor区中每熬过一次Minor GC,年龄就增长1岁,当它的年龄增长到必定程度(默认为15岁),就将会被晋升到老年代中。对象晋升老年代的年龄阈值,能够经过参数-XX:MaxTenuringThreshold设置。
4.动态对象年龄判断
虚拟机并非严格要求对象年龄必须达到MaxTenuringThreshold才能晋升老年代,若是子啊Survivor空间中相同年龄全部对象大小和总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就能够直接进入老年代,无需等到MaxTenuringThreshold中要求的年龄。
5.空间分配担保
在发生Minor GC以前,虚拟机会先检查老年代最大可用的连续空间是否大于新生代全部对象总空间,若是该条件成立,则Minor GC能够肯定是安全的。若是不成立,则虚拟机会查看HandlePromotionFailure设置值是否容许担保失败。若是容许,那么会检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小,若是大于,将尝试进行一次Minor GC,尽管此次的Minor GC是有风险的;或者HandlePromotionFailure设置不容许冒险,那这时也要改成进行一次Full GC。
新生代使用复制收集算法,为了内存利用率,只是用其中一个Survivor空间来做为轮换备份,所以当出现大量对象在Minor GC后仍然存活的状况,就须要兰年度进行分配担保,吧Survivor没法容纳的对象直接进入老年代。老年代要进行这样的担保,前提是老年代自己还有容纳这些对象的剩余空间。
JDK1.6以后的规则变为只要老年代的连续空间大于新生代对象总大小或者历次晋升的平均大小就会进行Minor GC,不然将进行Full GC。HandlePromotionFailure参数不会再影响到虚拟机的空间分配担保策略。