JVM - 2. GC 垃圾回收器简介
GC 垃圾回收器简介
程序计数器, 虚拟机栈, 本地方法栈 3个区域都在线程上分配, 随线程生, 随线程灭.
而堆(Java Heap)上的空间就需要 GC 来回收了.
至于方法区, 虽然也在堆上, 但是它存储的东西变化比较小, 所以它的垃圾回收机制又会不同.
那么, 怎么判断对象是否该回收呢? 判定方法有:
- 引用计数法
- 可达性分析算法
要回收的对象找到了, 该进行回收了, 那么用什么策略进行回收呢?
- 标记-清除(适合存活对象多, 死亡对象少的)
- 复制算法(适合死亡对象较多, 存活对象少的)
- 标记-整理算法(适合存活对象多, 死亡对象少的)
这些算法并没有绝对的好坏之分, 不同的场景适合不同的算法, 所以, Java 也是根据对象的生存周期设计了不同的内存区域(分代).
GC 最大的问题是在确定要回收的对象时, 需要 Stop the world, 来枚举 GC Roots 根节点以统计哪些对象需要被回收.
Java 通过以下两种方式来实现:
- 安全点
- 安全区域
接下来, 就是实现了, HotSpot 定义了如下几种垃圾回收器:
新生代回收器:
- Serial (单 GC 线程, 复制算法)
- ParNew (多 GC 线程, 复制算法)
- Parallel Scavenge(多线程, 复制算法, 关注吞吐量)
老生代回收器:
- Serial Old (单线程, 标记-整理)
- Parallel Old (多线程, 标记-整理)
- CMS (单线程标记, 并发整理)
其他回收器:
- G1
可能的组合有:
-
Serial + Serial Old
-
ParNew + Serial Old
-
Parallel Scavenge + Serial Old
-
Serial + CMS (+ Serial Old)
-
ParNew + CMS (+ Serial Old)
-
Parallel Scavenge + Parallel Old
-
G1