什么是垃圾:
没有被引用的对象 就是垃圾。
定位的方式
reference count: 引用计数,即在对象上记录着有多少个引用指向它。(循环引用无法解决)
root searching: 根可达算法,根对象包含 线程栈变量,静态变量,常量池,JNI指针。(目前都使用)
常见的算法:
Mark Sweep: 标记清除, (碎片化严重,对象数量的增加会导致效率变低)
copying: 区域划分,两个区域倒,(效率高,但是浪费内存)。
Mark-compact: 标记整理(运行效率高 )
常见的垃圾回收器
各个java版本默认的垃圾回收器
从Java 1(JDK 1.0)开始到Java 21之间的各个Java版本默认的垃圾回收器经历了一系列的演变。以下是一些主要版本的Java默认垃圾回收器的概述:
版本 | 垃圾回收器 |
---|---|
JDK 1.0 - 1.2: | 这些早期版本的Java并没有提供垃圾回收器的选择,它们使用了一个简单的标记-清除算法。 |
JDK 1.3: | 引入了串行垃圾回收器(Serial GC),这是第一个真正意义上的垃圾回收器。 |
JDK 1.4: | 引入了并行垃圾回收器(Parallel GC),也称为吞吐量优先的垃圾回收器,它在Server模式下成为默认的垃圾回收器。 |
JDK 5 : | 引入了Parallel Scavenge收集器,它与Parallel Old收集器一起使用,成为JDK 5到JDK 7的默认垃圾回收器组合。 |
JDK 6: | 继续使用Parallel Scavenge和Parallel Old作为默认垃圾回收器。 |
JDK 7: | 默认垃圾回收器仍然是Parallel Scavenge和Parallel Old。 |
JDK 8: | 继续使用Parallel Scavenge和Parallel Old作为默认垃圾回收器。引入了G1(Garbage-First)垃圾回收器,在JDK 8中也可以通过参数-XX:+UseG1GC来启用。 |
JDK 9: | G1垃圾回收器成为默认垃圾回收器,适用于大型堆和需要可预测停顿时间的应用。 |
JDK 10 - 16: | 继续使用G1作为默认垃圾回收器。 |
JDK 17: | G1垃圾回收器仍然是默认选择,但引入了ZGC(Z Garbage Collector)作为实验性特性。 |
JDK 21: | JDK 21支持多种垃圾回收器,包括G1、Parallel和ZGC。G1继续作为默认垃圾回收器,而ZGC提供了极低的停顿时间,适用于需要非常低停顿时间的应用程序。 |
各个垃圾回收器的优缺点:
垃圾回收器 | 版本 | 使用地方 | 优缺点 |
---|---|---|---|
Serial | 1.3 | young | 单线程STW(stop the world) 垃圾回收期 (年轻代 和 老年代 通用) 小内存使用。垃圾清理时要暂停服务器,效率很低。 |
Serial Old | 1.3 | Old | 单线程STW(stop the world) 垃圾回收期 (年轻代 和 老年代 通用) 小内存使用。垃圾清理时要暂停服务器,效率很低。 |
ParNew: | 1.5~1.7 | young | STW(stop the world) 工作在年轻代的多线程 它对 Parallel Scavenge进行了增强 和 CMS做配合使用。 |
CMS | 1.5~1.7 | old | concurrent mark sweep 异步并行的垃圾回收方式。采用的是 incremenetal update 算法存在bug,会存在漏标的情况。 在 1.5 1.6 1.7 之前没有好的并发垃圾回收器,大内存下的无奈选择,所以一直没有成为默认的垃圾回收期。 |
Parallel Scavenge: | 1.4~1.8 | young | STW(stop the world) 工作在年轻代的多线程 |
Parallel Old: | 1.4~1.8 | old | STW(stop the world) 工作在年轻代的多线程 |
G1: | 1.8以后 | all | STW(stop the world) 物理不分带,逻辑分代, 内存分成很多小区域,小区域就通过copy 算法来垃圾回收,年轻代和老年代视情况而定 |
ZGC: | 1.4~1.8 | young old | 不在分代,也不在停顿 |
shenandosh: | 12 | young old | STW(stop the world) 工作在年轻代的多线程 |
Epsilon: | young old | 不需要垃圾回收器,用于java程序运行完就收工的,内存直接清0 ,不需要回收 |