然而实际在开发中,并不是所有对象都能这样进行GC流程。当对象过大时或特别大时,因为占用幸存者区空间过大或大于幸存者区,而造成反复GC,重复复制大对象增加GC时间问题,当然JVM对这方面有专门的优化。而这个机制就是
大对象直接进入老年代
,使用JVM参数-XX:PretenureSizeThreshold
(单位为字节)设置大对象的大小,如果对象超过设置的大小会直接进入老年代,防止大对象进入年轻代造成重复GC。
大对象就是需要大量连续内存空间的对象,即数组,字符串。
注意:该参数只在Serial和ParNew收集器才会生效,即Serial与ParNew存在该参数进行大对象区分。
补充: -XX:+UseSerialGC
采用Serial收集器
JVM采用分代收集来实现内存管理,就必须区分
不同对象进入不同代中进行不同
的处理,而JVM的解决方法是:给每一个对象设置对象头中的对象年龄计数器(Age)
对象流程:
设置进入老年代年龄阈值:
-XX:MaxTenuringThreshold
在JVM中还有一种年龄判断机制:当一批对象的总大小大
大于
Survivor区域的50%,此时大于该批对象中的最大年龄的对象,直接进入老年代。
-XX:TargetSurvivorRatio
进行指定该机制是为了使多次进行GC后还存在的对象更早进入老年代,至于为什么是大于50%Survivor区的对象,实际上Eden区和Survivor区中很少存在3,4次还幸存对象
其实就是一种根据经验来将迟早会进入老年代的对象提前进入
老年代剩余可用空间
大小之和
大于老年代剩余可用空间
时
如果配置JVM参数
-XX:-HandlePromotionFailure
老年代剩余可用空间
是否大于历史minor gc
后进入老年代的对象平均大小
老年代剩余可用空间
小于进入老年代对象的平均大小
或未设置时,将触发Full gc老年代剩余可用空间
大于进入老年代对象的平均大小
时,触发minor gc
,如果minor gc后存活并需要移动到老年代的对象总大小
还是大于老年代的可用空间,也将会触发Full gc
Full gc对老年代和年轻代一起回收垃圾,诺Full gc后老年代的可用空间还是无法存放minor gc后需要进入老年代的对象,将会抛出
OOM
错误。
该机制是为了尽可能的减少Full gc,并且哪怕无法避免full gc也可以在一定程度上减少年轻代对老年代的引用,加快了GC效率