关于:“JVM中一次完整的GC流程是怎样的,对象如何晋升到老年代”这个问题,在面试过程中遇到的频率非常高。
关于这个问题,我们可以先描述Java堆内存的划分,再解释Minor GC、Major GC、Full GC,最后再描述他们之间的转化流程。
以下是我的回答思路:
Java堆内存是由新生代和老年代组成,其中新生代又包括Eden区、Survivor区[S0、S1]。
一个新的对象,首先会分配在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的压力和耗时。在Young GC之后,存活的对象将被复制到Survivor区或Old区,而Eden区会被完全清空,等待下一次对象的分配。
Major GC其实是Full GC的另外一种叫法。