前言
今天来分享一道比较好的面试题,JVM 中一次完整的 GC 流程是怎样的以及对象如何晋升到老年代?对于这个问题,我们一起看看考察点和比较好的回答吧。
考察点
Java 虚拟机能够替我们回收内存空间,清除垃圾对象,因此了解其垃圾回收机制以及 JVM 是如何对堆内存管理考验的正是程序员的功底,了解了这方面的知识,才能够写出高质量的代码,避免内存泄漏,减少内存溢出等问题。这个问题就是面试官想考察我们是不是对 JVM 学习了解过以及对堆内存管理的认识。
回答
关于这个问题,我们在回答的时候先对 Java 堆内存的划分,再解释Minor GC、Major GC、Full GC最后再描述他们之间的转化流程。
JVM 的堆内存划分:堆内存是由新时代和老年代组成,新生代又包括 Eden 区、Survivor 区其中包括 S0、S1。
JVM 创建一个新的对象,首先会分配在 Eden 区(如果是大对象,会直接进入老年代),当 Eden 区满了以后,JVM 会触发一次 Minor GC,用来回收 Eden 区的垃圾。Eden 区存活下来的对象,会转移到Survivor 区。如果对象是在 Eden中出生,并经过第一次 Minor GC 后仍然存活,那这个时候,该对象的 GC 年龄会设置成 1。每熬过一次 Minor GC 该对象的 GC 年龄都会进行累加,如果超过默认的GC次数 15 次,这个对象就会转移到老年代。
当老年代满了无法容纳更多对象的时候,就会触发 Full GC,Full GC 会清理整个内存堆,包括年轻代、老年代。需要注意的是在进行 Full GC 之前,通常会先进行一次 Young GC,以尽可能地清理掉Eden 区和 Survivor 区中的垃圾对象,以减少 Full GC 的压力和耗时。在 YoungGC 以后,存活的对象将被复制到 Survivor 区或Old 区,而 Eden 区会被完全清空,等待下一次对象的分配。Major GC其实就是Full GC的另一种叫法。
以上就是我对于这个问题的理解。
总结
JVM 对堆内存进行分代管理,实现高效的垃圾回收,理解这些要有一定的技术积累。这个题目考察范围是在3年以上的程序员,希望读完这篇文章你有所收获。想要收获更多 JVM 面试题可参考下图。