本文为Java后端面试自学内容,记于此以便学习和回忆,如有侵权或错误,欢迎讨论指教;如果转载请注明出处!
垃圾回收GC主要完成三件事:
1 需要回收哪些内存
2 什么时候回收
3 如何回收
1 需要回收哪些内存
- 引用计数法
在Java 中,引用和对象是有关联的。如果要操作对象则必须用引用进行。因此,很显然一个简单的办法是通过引用计数来判断一个对象是否可以回收。简单说,即一个对象如果没有任何与之关联的引用,即他们的引用计数都不为0,则说明对象不太可能再被用到,那么这个对象就是可回收对象。
- 可达性分析法
为了解决引用计数法的循环引用问题,Java 使用了可达性分析的方法。通过一系列的“GC roots”对象作为起点搜索。如果在“GC roots”和一个对象之间没有可达路径,则称该对象是不可达的。要注意的是,不可达对象不等价于可回收对象,不可达对象变为可回收对象至少要经过两次标记过程。两次标记后仍然是可回收对象,则将面临回收。
2 什么时候回收
先说几个概念
Minor GC是清理年轻代(包括 Eden 和 Survivor 区域)
Major GC 是清理永久代
Full GC 是清理整个堆空间—包括年轻代和永久代
Minor GC触发条件:
Eden区满,即触发Minor GC
Major GC触发条件:
许多 Major GC 是由 Minor GC 触发的。在进行MajorGC 前一般都先进行了一次MinorGC,使得有新生代的对象晋身入老年代,导致空间不够用时才触发。当无法找到足够大的连续空间分配给新创建的较大对象时也会提前触发一次MajorGC 进行垃圾回收腾出空间。
Full GC触发条件:
- 调用System.gc(),建议执行
- 老年代空间不足
- 方法区(永久代,元空间,metaspace)空间不足
- 通过Minor GC进入老年代大于老年代的大小
3 如何回收
GC收集算法
- 标记清除
- 复制
- 标记整理
- 分代收集
GC收集器
Serial (单线程 复制算法)
ParNew (serial+多线程)
Parallel Scavenge (多线程复制算法)
Serial Old (单线程标记整理)
Parallel Old (多线程标记整理)
CMS收集器 (多线程标记清除)
G1收集器