欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JVM进入老年代情况

程序员文章站 2023-11-13 13:22:04
1.躲过15次GC之后进入老年代 默认的设置下,当对象的年龄达到15岁的时候,也就是躲过15次Gc的时候,他就会转移到老年代中去 这个具体是多少岁进入老年代,可以通过JVM参数 “-XX:MaxTenuringThreshold”来设置,默认情况是15岁 2.动态对象年龄判断 假如说当前放对象的Su ......

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左右的对象会进入老年代,此时老年代空间是狗的

如果