大家好,我是锋哥。今天分享关于【说下JVM中一次完整的GC流程?】面试题。希望对大家有帮助;
说下JVM中一次完整的GC流程?
1000道 互联网大厂Java工程师 精选面试题-Java资源分享网
JVM中的一次完整的垃圾回收(GC)流程可以概括为以下几个步骤:
1. 标记阶段 (Mark)
- 目标:找出所有"存活"的对象。
- 过程:JVM的垃圾回收器首先通过从GC Root开始遍历对象图,标记所有可达的对象。GC Root通常是线程栈、静态字段和本地方法栈等可以直接访问的对象。
- 标记过程需要跟踪从GC Root出发可达的对象,标记所有与GC Root有路径连接的对象。
2. 清除阶段 (Sweep)
- 目标:清除所有没有被标记的对象,即"不可达"对象。
- 过程:GC将遍历堆中的对象,将那些没有被标记为可达的对象删除。这个过程释放内存空间,垃圾对象将被回收并且内存可重新分配。
- 注意:在某些情况下,如垃圾回收器没有合并内存(例如Serial GC,Parallel GC等),清除后可能会导致内存碎片。
3. 整理阶段 (Compact)
- 目标:防止内存碎片。
- 过程:如果是整理式垃圾回收(如Old Generation的Full GC),在回收不可达对象后,内存区域中的存活对象会被整理,使得这些对象紧凑地排列在一起。这样做的目的是减少内存碎片,使得对象能够高效地分配,避免频繁的垃圾回收。
- 整理的过程一般会将存活的对象向内存区域的一端移动,合并出一个连续的大块空闲内存区域。
4. 更新指针
- 目标:更新引用。
- 过程:经过标记和整理之后,可能会有一些对象的引用地址发生了变化。在这个阶段,JVM会更新所有引用被回收对象的指针,使得它们指向新的位置。
5. 结束阶段 (Finalization)
- 目标:执行对象的终结方法。
- 过程:在对象被回收之前,JVM可以调用对象的
finalize()
方法。如果该对象覆盖了finalize()
方法,JVM会调用该方法用于做一些清理工作(如关闭资源等)。需要注意的是,finalize()
方法的调用并非是GC过程的一部分,且不是所有垃圾回收都会触发它。
GC类型
JVM中有多种GC算法,其中最常见的几种是:
- Serial GC:适合单线程环境,它在回收过程中会暂停整个应用线程。
- Parallel GC:多个线程并行工作,加速垃圾回收。
- CMS GC (Concurrent Mark-Sweep):并发回收标记阶段和清除阶段,以减少停顿时间。
- G1 GC:分代回收与并行回收相结合,目标是减少停顿时间,并且适应大堆内存的环境。
垃圾回收过程的细节
在不同的GC算法中,GC的过程会有所不同,特别是在停顿时间、并行性、内存整理等方面的表现。在实际应用中,选择合适的垃圾回收算法对于提高JVM的性能至关重要。
小结
JVM中的垃圾回收流程大致如下:
- 标记阶段:标记所有可达的对象。
- 清除阶段:回收不可达的对象,释放内存空间。
- 整理阶段:整理内存,避免碎片。
- 更新指针:更新引用地址。
- 结束阶段:调用
finalize()
方法(可选)。
在不同的GC算法中,标记、清理和整理的顺序及策略可能有所不同,但大体流程一致。