垃圾回收器在规范中没有过多的规定,可以由不同的厂商,不同的JVM来实现。
分类
-
按线程数分,可分为串行垃圾回收器和并行垃圾回收器。
-
按工作模式分,可分为并发式垃圾回收器和独占式垃圾回收器。
并发式:用户线程和垃圾回收线程交替执行,可以减少程序的停顿时间,用户体验更好。
独占式:一旦开始垃圾回收,就停止所有用户线程的执行,直到垃圾回收结束。
- 按碎片的处理方式分,可分为压缩式垃圾回收器和非压缩式垃圾回收器。
压缩式垃圾回收器:在垃圾回收完成后,会对存活的对象进行压缩整理,消除内存碎片。再分配对象使用指针碰撞。
非压缩垃圾回收器:没有整理的步骤。再分配对象使用空闲列表。 - 按工作的内存区间分,可分为新生代的垃圾回收器和老年代的垃圾回收器。
GC主要性能指标
- 吞吐量:用户代码运行的时间比上程序总运行时间(垃圾回收时间a,用户代码运行时间b,吞吐量=b/(a+b))。
- 暂停时间:执行垃圾回收线程时,用户线程的暂停时间。
- 内存占用:Java堆区所占的内存大小。
吞吐量与低延时
- 吞吐量高,程序运行总时间就少,直觉上吞吐量越高程序运行得越快。
- 延时低,在用户与程序交互的场景时,卡顿时间短,会让用户感觉程序更流畅,体验感更好,但其实总的运行时间是更长的。
- 高吞吐量与低暂停时间是一个互相竞争的目标。
如果选择吞吐量优先,则必然要降低垃圾回收的频率,导致一次垃圾回收需要更长的暂停时间。
如果希望更短的暂停时间,则必然需要更频繁的进行垃圾回收,以减少一次垃圾回收的暂停时间。这也导致了程序的总运行时间变长,吞吐量降低。
现在的标准是在最大吞吐量优先的情况下,降低停顿时间(在可控的暂停时间内,最大限度提高吞吐量)。
垃圾回收器历史
七款经典的垃圾回收器
- 串行回收器:(Serial)(Serial Old)
- 并行回收器:(ParNew)(Parallel Scavenge)(Parallel Old)
- 并发回收器:(CMS)(G1)
组合关系
JDK14状况JDK8:(Serial GC — CMS GC)(ParNew GC — Serial Old GC)is deprecated(废弃,还可以用)。
JDK9:(Serial GC — CMS GC)(ParNew GC — Serial Old GC)is removed(移除,不可以用)。
JDK14:(Parallel Scavenge GC — Serial Old GC)is deprecated(废弃,还可以用),CMS GC is removed(移除,不可以用)。
没有万能的垃圾回收器,应根据不同场景不同GC的特性选择最合适的GC。