Survivor区对象进入老年代前是否会被GC?及GC流程相关疑问
Java堆内存Minor GC相关问题解答
问题1:Survivor区中的对象是否会在进入老年代前被垃圾回收?
会被回收。Survivor区不是单纯的过渡缓冲带,每次触发Minor GC时,当前非空闲的Survivor区(SN)会和Eden区(YG)一起被扫描回收:
- 区域内的死亡对象直接被清理回收;
- 存活对象会先判断年龄是否达到晋升老年代的阈值(默认15次GC存活),达到则直接进入老年代(OG);未达到的话,会和YG的存活对象一起转移到空闲的Survivor区(SE)。
Survivor区的核心作用是筛选短命对象,减少老年代的GC频率,本身也会参与每次Minor GC的回收流程。
问题2:三种Minor GC执行流程算法哪个正确?
算法3是正确的,标准的Minor GC执行逻辑如下:
当YG内存耗尽触发Minor GC时,会同时对YG和当前非空闲的Survivor区(SN)执行垃圾回收:
- 扫描YG和SN,标记存活对象;
- SN中的存活对象:年龄达标则转移至OG,未达标则和YG的存活对象一起转移至空闲的Survivor区(SE);
- 回收完成后,SE和SN的角色互换,下次GC时使用新的空闲Survivor区。
另外两种算法的错误点:
- 算法1:错误地认为SN的对象会直接转移至OG,忽略了年龄阈值的判断,且SN的存活对象也可能转移至SE;
- 算法2:完全不符合实际逻辑,Minor GC不会先填充SN,也不会单独对SN执行GC,而是统一扫描YG和SN处理存活对象。
问题3:若YG存活对象数量超过SE容量的两倍或更多时,会出现什么情况?
当YG的存活对象(加上SN的存活对象)总大小超过SE的容量时,超出SE容量的部分会直接晋升到老年代(OG)。如果存活对象过多导致老年代剩余空间不足,还会触发Full GC来回收老年代的空间,极端情况下可能引发OOM(内存溢出)。
内容的提问来源于stack exchange,提问作者ABu
相关产品推荐
相关产品推荐

