JVM|有关Java的分代回收

JVM|有关Java的分代回收
文章图片
当我们创建一个对象的时候,首先被放在Eden区,然后不断的创建对象,将Eden区沾满了。
JVM|有关Java的分代回收
文章图片

当我再要想创建对象的时候,空间已经不够了,就要触发一次Minor GC,将存活的对象,复制到To区,寿命加1,然后清空Eden区,交换From和To区。
JVM|有关Java的分代回收
文章图片

【JVM|有关Java的分代回收】然后继续分配对象,直到再次满了
JVM|有关Java的分代回收
文章图片
触发第二次Minor GC,查看幸存者区和Eden区的对象是否能够被垃圾回收,将垃圾回收之后能够存活的对象,放入To区中,同时这些对象的寿命+1,清空垃圾对象,交换To和From区
JVM|有关Java的分代回收
文章图片
反复多次,直到幸存者区有对象的寿命达到15,即经历了15次垃圾回收,将这个对象晋升到老年代中
JVM|有关Java的分代回收
文章图片

如果晋升的对象多了,老年代满了怎么办,下面一种场景
JVM|有关Java的分代回收
文章图片

eden区也满了,老年代也满了,又来了一个很大的对象,Eden区放不下,老年代也放不下,触发MinorGC后,依然无法存储,此时会触发一次Full GC。

  • 对象首先分配在伊甸园区
  • 新生代空间不足时,触发minorGC,伊甸园和from存活的对象使用copy复制到to中,存活的对象年龄加1并且交换from/to
  • Minor GC会引发 "stop the world" ,在我发生垃圾回收的时候,我必须暂停其他的用户线程,等我完成垃圾回收之后,其他线程才可以继续运行,因为回收的过程中涉及到对象的移动,也会改变很多对象引用的地址,如果此时没有阻塞其他线程,就会造成一些错误,但是MinorGC暂停的时间非常短,因为很多对象就直接被回收掉了,真正需要移动到幸存者区的对象是非常少的。
  • 当对象的寿命超过阈值的时候,会晋升到老年代,阈值最大是15次,age保存在对象头中,占4bit,最大能表示的是1111,即15
  • 当老年代空间不足,先尝试进行MinorGC,如果GC之后还不足,会触发Full GC,stop the world时间更长,老年代采用的是标记清除/整理算法


    推荐阅读