JVM进入老年代情况
1.躲过15次gc之后进入老年代
默认的设置下,当对象的年龄达到15岁的时候,也就是躲过15次gc的时候,他就会转移到老年代中去
这个具体是多少岁进入老年代,可以通过jvm参数 “-xx:maxtenuringthreshold”来设置,默认情况是15岁
2.动态对象年龄判断
假如说当前放对象的survivor区域里一批对象的总大小大于了这块survivor区域的内存大小的50%,那么此时大于等于这批对象年龄的对象,就可以直接进入老年代了
另外我们要理清楚一个概念,这个实际这个规则运行的时候是如下的逻辑:年龄1+年龄2+年龄n的多个年龄对象总和超过了survivor区域的50%,此时就会把年龄n以上的对象都放入老年代
在没有回收的情况下 所有对象存活着
比如说一块s区块 100m 如果第一次有20m 不到老年代 第二次来了51m存活 如果之前的20m全部存活,那么这51m和20m将全部到老年代
另外一种情况 在这3次的对象都持续引用,不能回收的情况下,比如说一块s区块 100m 如果第一次有10m 不到老年代 第二次20m 第三次 31m 那么就会由于20+31>50了 那么第一次的10m就会到老年代了。
3.大对象直接进入老年代
有一个jvm参数,就是 -xx:pretenuresizethreshold“,可以把他的值设置为字节数,比如“1048576”,就是1m
如果你创建一个大于这个大小的对象,比如一个超大的数组,或者是别的啥东西,此时就直接把这个大对象放在老年代中,压根不会经过新生代,这样可以避免新生代出现那种大对象,然后在2个survivor区域里回来复制多次之后才能进入老年代
4.minorgc后的对象太多无法放入survivor区怎么办?
如果在minor gc之后发现剩余的存活对象太多了,没办法放入另外一块survivor,那么这个时候就必须得把这些对象直接转移到老年代中去
5.老年代空间分配担保规则
在执行任何一次minor gc之前,jvm会检查一下老年代可用的可用内存空间,是否大于新生代所有对象的总大小
为啥会检查这个呢?因为最极端的情况下,可能新生代的minor gc过后,所有对象都存活下来了,那岂不是新生代所有对象全部都要进入老年代?
如果说发现老年代的内存大小是大于新生代所有对象的,此时就可以放心大胆的对新生代发起一次minor gc了,也可以转移到老年代去。
但是假如执行minor gc之前,发现老年代的可用内存已经小于了新生代的全部对象大小了,那么这个时候是不是有可能在minor gc之后新生代的对象全部存活下来,然后全部需要转移到老年代去,但是老年代空间又不够?
所以假如minor gc之前,发现老年代的可用内存已经小于看新生代的全部对象大小了,就会看一个-xx:-handlepromotionfailure的参数是否设置了,如果有这个参数,那么就会继续进行下一步判断,
下一步判断,就是看老年代的内存大小,是否大于之前每一次minor gc后进入老年代的对象的平均大小。
举个例子,之前每次minor gc后,平均都有10mb左右的对象会进入老年代,那么此时老年代可用内存大于10mb
这就说明很可能这次minor gc过后也是差不多10mb左右的对象会进入老年代,此时老年代空间是狗的
如果