jvm大对象直接进入老年代_java版村民繁殖条件「建议收藏」

jvm大对象直接进入老年代_java版村民繁殖条件「建议收藏」1.躲过15次GC之后进入老年代系统刚启动时,创建的各种各样的对象,都是分配在年轻代里

1.躲过15次GC之后进入老年代

系统刚启动时,创建的各种各样的对象,都是分配在年轻代里。随着慢慢系统跑着跑着,年轻代满了,就会出发Minor GC ,可能1%的少量存活对像转移到空着的Survivor区中,然后系统继续运行,继续在Eden区里分配对象……..,类似静态变量等引用的对象,可能存活时间会久一些,无论年轻代中怎么垃圾回收,类似这种对象都不会被回收掉。而此对象每次在年轻代里躲过一次Minor GC被转移到一块Survivor区域中,他的年龄就会增加一岁,默认的设置下,当对象的年龄达到15岁时,也就是躲过15次GC的时候,他就会转移到老年代里去,具体是多少岁进入老年代,可以通过JVM参数“-XX:MaxTenuringThreshold”来设置,默认是15岁

 

2.动态对象年龄判断

这里跟这个对象年龄有另外一个规则可以让对象进入老年代,不用等到15次GC过后才可以。

他的大致规则就是,假如说当前放对象的Survivor区域里,一批对象的总大小大于了这块Survivor区域的内存大小的50%,那么此时大于等于这批对象年龄的对象,就可以直接进入老年代了。

jvm大对象直接进入老年代_java版村民繁殖条件「建议收藏」

假设这个图中的Survivor2区有两个对象,这俩对象的年龄一样,都是2岁,然后俩对象加起来内存超过了50MB,这个时候,Survivor2区里大于等于2岁的对象,都要进入老年代里去。这就是动态年龄判断的规则,这条规则也会让一些年轻代的对象进入老年代,另外实际这个规则运行的时候是如下的逻辑:年龄1+年龄2+年龄n的多个年龄对象总和超过了Survivor区的50%,此时就会把年龄n以上的对象都放入老年代。

 

3.大对象直接进入老年代

有一个JVM参数,就是“-XX:PretenureSizeThreshold”,可以把它的值设置为字节数,比如“1048576”字节,就是1MB,意思就是如果你要创建一个大于这个大小的对象,比如一个超大的数组,或者是别的啥东西,此时就直接把这个大对象放到老年代里去,压根不会经过年轻代。之所以这么做,是因为要避免年轻代里出现那种大对象,然后屡次躲过GC,还得把他在两个Survivor区域里来回复制多次之后才能进入老年代。所以说这也是一个对象进入老年代的规则

 

4.Minor GC后的对象太多,无法放入Survivor区

如图所示:

jvm大对象直接进入老年代_java版村民繁殖条件「建议收藏」

这个时候就必须得把这些对象直接转移到老年代去!

5.老年代空间分配担保规则

如果年轻代里大量对象存活,确实自己的Survivor区放不下了,必须转移到老年代去

但是如果老年代里空间也不够放这些对象,改怎么办呢?

首先,在执行任何一次Minor GC之前,JVM都会先检查一些老年代可用的内存空间,是否大于年轻代所有对象的总大小,为什么呢?因为最极端的情况下,可能年轻代Minor GC之后,所有对象都存活下来了,那岂不是年轻代所有对象全部进入老年代

jvm大对象直接进入老年代_java版村民繁殖条件「建议收藏」

如果说发现老年代内存大小是大于年轻代所有对象的,此时就可以放心大胆地对年轻代发起一次Minor GC了。

但是假如执行Minor GC之前,发现老年代的可用内存已经小于了年轻代的全部对象大小了

恰好这个时候Minor GC之后年轻代的对象全部存活下来,全部需要转移到老年代中去,但是老年代内存空间又不够?

所以假如Minor GC之前,发现老年代的可用内存已经小于了年轻代的全部对象大小,就会看一个“-XX:-HandlePromotionFailure”的参数是否设置了

如果有这个参数,那么就会看看老年代的内存大小,是否大于之前每一次Minor GC后进去老年代对象的平均大小

jvm大对象直接进入老年代_java版村民繁殖条件「建议收藏」

 

但是如果上面步骤判断失败了,或者是“-XX:-HandlePromotionFailure”参数没设置,此时就会直接触发一次“Full GC”,

就是对老年代进行垃圾回收,尽量腾出来一些内存空间,然后再执行Minor GC。

如果上面两个步骤判断成功,那么就可以尝试Minor GC,此时进行Minor GC有几种可能:

①Minor GC过后,剩余的存活对象的大小,小于Survivor区的大小,那么此时存活对象进入Survivor区即可

②Minor GC过后,剩余的存活对象的大小,大于Survivor区的大小,但是小于老年代可用内存大小,就直接进入老年代即可

③Minor GC过后,剩余的存活对象的大小,大于Survivor区的大小,同时大于老年代可用内存大小,此时就会发生“Handle Promotion Failure”的情况,这个时候就会出发一次“Full GC”。

Full GC就是对老年代进行垃圾回收,同时也一般会对年轻代进行垃圾回收。

如果Full GC之后,老年代还是没有足够空间存放Minor GC过后的剩余存活对虾,此时就会导致所谓的“OOM”内存溢出

所以,所谓的JVM优化,就是尽可能的让对象都在年轻代里分配和回收,尽量别让太多对象频繁进入老年代,避免频繁对老年代进行垃圾回收,同时给系统充足的内存大小,避免年轻代频繁的进行垃圾回收。

今天的文章jvm大对象直接进入老年代_java版村民繁殖条件「建议收藏」分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/84982.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注