JVM的参数和知识点太多啦,记录下来,供自己随时回顾。
- java对象什么时候进入年轻代(新生代)?
- java对象什么时候进入老年代?
- 对象优先在Eden分配
- 大对象直接进入老年代
- 空间分配担保机制
java对象什么时候进入年轻代(新生代)?
当对象首次创建时, 会放在新生代的eden区, 如果不被GC回收,会一直在eden区
java对象什么时候进入老年代?
- 当新生代的对象进行多次YGC之后还一直存在并且达到设置的周期(默认15),会进入老年代。参数:-XX:MaxTenuringThreshold=15
- 一个Survivor区域中对象大小的总和加起来超过该区域50%,那么大于或者等于这个对象年龄的对象就会进入到老年代。这也就是JVM的动态对象年龄判断。 举个栗子:参数-XX:TargetSurvivorRatio=50 默认50%
对象优先在Eden分配
对象首先进入Eden区域,Eden区域满时会进行一次YGC,把存活对象放入S1区,再对Eden区域进行垃圾回收。第二次Eden区域满时进行第二次YGC,此时S1区的存活对象和Eden的存活对象被复制到S2区,Eden区的垃圾对象再次被回收
设置参数:-XX:SurvivorRatio=8
设置Eden区比例为80%,S1 和 S2 各为10%;若设置为5,Eden:两个S区 为5:1:1
大对象直接进入老年代
为了避免对象在Eden区、S1、S2区进行大量的内存复制,当大对象进入时,直接进入老年代。 配置参数:-XX:PretenureSizeThreshold=1M 当对象大于1M时,直接进入老年代
空间分配担保机制
在执行任何Minor GC(YGC)之前,虚拟机会先检查老年代最大可用的连续空间是否大于新生代对象总空间,如果这个条件成立,那么Minor GC可用确保是安全的,如果不成立,则虚拟机会查看HandlePromotionFailure设置值是否允许担保失败,如果允许,会继续检查之前历次Minor GC中晋升到老年代的平均对象大小是否<老年代最大可用的连续空间,如果小于,将尝试进行一次Minor GC,这次GC是由风险的,如果大于或者HandlePromotionFailure设置为false,那么这时要进行一次Full GC,为可能晋升到老年代的对象腾出空间。
风险指的是什么?指的是极端情况下MGC之后所有对象依旧存活,对象全部要进入老年代,如果老年代空间不够用,就会触发一次Full GC。如果Full GC之后老年代空间还是不够用,会触发OOM。
这块太绕了。。简单一点
if(需要进行一次Minor GC){if(老年代可用空间 > 新生代所有对象大小){执行一次Minor GC;}else{if(-XX:-HandlePromotionFailure=true){if(老年代连续可用空间>之前晋升到老年代所有大小的平均值){执行Minor GC;/*执行之后有3种情况:1.剩余对象大小小于S区大小,对象进入S区2.剩余对象大小大于S区,对象进入老年代3.剩余对象大小大于S区,也大于老年代,执行一次Full GC。如果执行Full GC之后还是放不下晋升对象,报错OOM*/}else{执行Full GC;执行Minor GC;}}}}