Java入门之了解JVM(32)

新生对象首先在Eden分配到内存,当Eden区将要内存溢出时将会出发一次Minor GC,Minor GC过后还存活的对象将会被复制到s0当s0就要满时也会触发Minor GC,并将s0中存活的对象复制到s1; 注意,这时s1将变更为s0(from),而原来的s0就变为s1(to),既角色进行互换那什么时候新生代的对象会被转移到老年代呢?

在jvm中每个对象都是有年龄限制的,每当经过一次gc岁数就增加1,直到到达年龄界限都还没被gc回收的话,它就会被转移到老年代在jvm有个专门用来设置所谓“够岁”的参数,+XX:MaxTenuringThreshold,该参数默认为15还有一种情况新生代中的对象会进入老年代,就是当s1(to)没有足够空间容纳复制过来的对象时且对象的使用率高于-XX:TargetSurvivorRatio值,这时并不会理会+XX:MaxTenuringThreshold为什么需要2块survivor内存?

这个问题我自己的理解是为了提高内存的使用效率(原为复制算法是1:1的现在是8:1:1)和减少Full GC(会造成stop the world现象,对新生代,老年代,方法去(1.8前叫永久代)一起GC)的发生频率,为什么呢?如上面提到的老年代中存放的都是长寿的对象,现在假设有这么一种情况,老年代就快要满了但还没到达Full GC的条件,这时新生代有些顽强对象经过15次GC都杀不死,就要转移到老年代了,这个时候,JVM是需要进行空间分配担保操作,通俗点说就是通过分析查看老年代所剩下的空间来判断是否能够容纳即将到来的对象,如果不能容纳,即担保失败,就会发生Full GC来腾出空间;那么通过2块survivor内存的来回复制,可以让Eden区腾出更大的空间,因为如果只有Eden和1块survivor的话,survivor经过Minor GC后但又没够转移到老年代的条件,那么就会将存活的对象重新复制到Eden,这样Eden的空间就变少了,就降低了Eden内存的使用使用效率; 那么当Eden内存效率提高了survivor区就不会那么快满,从而减少了对象进入老年代的几率再从而减少Full GC的发生

推荐阅读