总所周知JVM的Heap是分代管理的,如下:
那么一个对象从创建到回收的流程是怎么样的?
-
JVM启动后,第一次YGC之前,S0、S1区都是空的,所有新创建的对象都是分配在eden区的
-
当eden区空间占满时,会触发YGC。会将没有引用到的对象(下称"死亡的对象")删除,将有引用的对象(下称"存活的对象")复制到S0区,并将对象的age加1,然后将整个eden区全部清空
-
下一次YGC时,eden区发生的动作同步骤2,(删除死亡的对象,将存活的对象复制到幸存者区),不过这次是将有引用的对象复制到S1区。同时将之前S0区的存活的对象也复制到S1区后,并将这些"幸存"下来的对象age加1。(这就是为什么S0和S1区大小一般相同)此时将eden区和S0区的数据全部清空。
-
下一次YGC时,eden区发生的动作类似,(删除死亡的对象,将存活的对象复制到幸存者区),只不过这次又会将存活的对象再次复制到S0区,并将留下来的对象age加1。此时将eden和S1的数据清空。
-
经过步骤2~步骤4 类似往复,每次YGC时,将存活的对象交替复制到S0和S1区,将eden和另一个幸存者区的数据清空。直到YGC后,幸存者区的对象有超过一定age(jdk8默认是15,可配置),这是会将对象复制到Old generation
-
YGC会持续不断的进行,所以对象也会持续不断地从Young generation复制到Old generation
-
以上步骤几乎涵盖了Young generation的整个过程。 最后,当heap可用空间不足以给新建对象时则会进行Major GC,以清理和压缩空间。 至于何时进行Major GC,可参考:GC模式
参考:https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html#t3