JVM堆主要有两块:新生代和老年代,JAVA1.8后把持久代改成元空间Meta space
新生代包括Eden,和两个survivor.老年代就是老年代那一块.
当生成新的对象时,对象进入新生代的Eden区域,Eden满后,触发新生代GC,会对Eden和当前正在使用的survivor进行垃圾回收(如果都没有使用则任选一个即可),把这俩区域未被回收的对象全部复制到另一个survivor,然后清空Eden和以前那个survivor。
再次生成对象时,会重复上面的步骤。
如果survivor盛不下了装满了,则会将里面的部分对象复制到老年代里。
JVM将对象提升到老年代里的策略是:
- 年龄,经历新生代GC的次数代表对象的年龄,默认是15
- 大小,即占用内存空间的大小
假如老年代也装不下了,就会进行FULL GC,不管是新生代还是老年代,全部GC,FULL GC耗时很长。
一些关于GC的JVM参数:
选项 默认值 作用
-XX:InitialSurvivorRatio 8 新生代Eden/Survivor空间的初始比例
-XX:SurvivorRatio 8 新生代Eden/Survivor空间的比例
-XX:MinSurvivorRatio 3 新生代Eden/Survivor空间的最小比例
-XX:TargetSurvivorRatio 50 垃圾回收后期望的Survivor区空间使用率
-XX:InitialTenuingThreshold 7 晋升到老年代的对象年龄初始阀值
-XX:MaxTenuringThreshold 15 晋升到老年代的年龄阀值
-XX:PretenureSizeThreshold 0 直接晋升老年代的对象大小
-XX:UsePSAdaptiveSurvivorSizePolicy true 自适应调整Survivor区域大小策略