Java垃圾回收器(Garbage Collector)概述
1. 分类 1.1按线程数分 可以分为串行垃圾回收器和并行垃圾回收器。
-
串行垃圾回收器 串行回收指的是在同一时间段内只允许有一个CPU用于执行垃圾回收操作,此时工作线程被暂停,直至垃圾收集工作结束。 在诸如单CPU处理器或者较小的应用内存等硬件平台不是特别优越的场合,串行回收器的性能表现可以超过并行回收器和并发回收器。所以,串行回收默认被应用在客户端的Client模式下的JVM中。 -
并行垃圾回收器 并行回收可运用多个CPU同时执行垃圾回收,因此提升了应用的吞吐量,不过并行回收仍然与串行回收一样,采用独占式,使用了“Stop-the-world” 机制。 在并发能力比较强的CPU上,并行回收器产生的停顿时间要断于串行回收器。
知识点补充:并行和并发 并发:一个CPU(采用时间片)同时执行多个任务。 并行:多个CPU同时执行多个任务。
举例:你吃饭吃到一半,电话来了,你一直到吃完了以后才去接,这就说明 你不支持并发也不支持并行。 你吃饭吃到一半,电话来了,你停了下来接了电话,接完后继续吃饭,这说明你支持并发。 你吃饭吃到一半,电话来了,你一边打电话一边吃饭,这说明你支持并行。
1.2按照工作模式分 可以分为并发式垃圾回收器和独占式垃圾回收器。
-
并发式垃圾回收器与应用程序线程交替工作,以尽可能减少应用程序的停顿时间。 -
独占式垃圾回收器(Stop the world)一旦运行,就停止应用程序中的所有用户线程,直到垃圾回收过程完全结束。 1.3按碎片处理方式分 可分为压缩式垃圾回收器和非压缩式垃圾回收器。 -
压缩式垃圾处理器会在回收完成后,对存活对象进行压缩整理,消除回收后的碎片。再分配对象空间使用:指针碰撞。 -
非压缩式的垃圾回收器不进行这步操作。再分配对象空间使用:空闲列表。 1.4按工作的内存区间分 可分为年轻代垃圾回收器和老年代垃圾回收器。
2.评估GC的性能指标
-
吞吐量:运行用户代码的时间占总运行时间的比例。 (总运行时间=程序的运行时间+内存回收的时间) -
垃圾收集开销:吞吐量的补数,垃圾收集所用时间与总运行时间的比例。 -
暂停时间:执行垃圾收集时,程序的工作线程被暂停的时间。 -
收集频率:相对于应用程序的执行,收集操作发生的频率。 -
内存占用:Java堆区所占的内存大小。 -
快速:一个对象从诞生到被回收所经历的时间。
3.吞吐量VS暂停时间 “高吞吐量”和“低暂停时间”是一对相互竞争的目标。 因为如果选择以吞吐量优先,那么必然需要降低内存回收的执行频率。但是这样会导致GC需要更长的暂停时间来执行内存回放。(STW-Stop the world)
相反的,如果选择以暂停时间优先为原则,那么为了降低每次执行内存回收时的暂停时间,也只能频繁的执行内存回收,但这又引起了年轻代内存的缩减和导致程序吞吐量的下降。 在设计(或使用)GC算法时,我们必须确定我们的目标:一个GC算法只可能针对两个目标之一(即只专注于较大吞吐量或最小暂停时间),或尝试找到一个二者的折中。 现在的标准:在最大吞吐量优先的情况下,降低停顿时间。 4.垃圾回收器发展史
5.七种经典的垃圾回收器 串行回收器:Serial、Serial Old 并行回收器:ParNew、Parallel Scavenge、Parallel Old 并发回收器:CMS、G1
- 七种垃圾回收器与垃圾分代之间的关系
- 垃圾回收器的组合关系
当CMS GC回收失败时,Serial Old GC是CMS GC的后备方案。虚线代表的是后续版本弃用了某个组合或GC。 6.G1回收器-区域化分代式 官方给G1(Garbage-First)设定的目标是再延迟可控的情况下获得尽可能高的吞吐量,所以才担当起“全功能收集器”的重任与期望。 G1是一个并行回收器,他把堆分割为很多不相关的区域。使用不同的Region来表示Eden、幸存者0区、幸存者1区、老年代等。 G1 GC有计划地避免在整个Java堆中进行全区域的垃圾收集。G1跟踪各个Region里面的垃圾堆积的价值大小(回收所获得的空间大小以及回收所需的时间的经验值),在后台维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的Region。 7.革命性的ZGC 目前是实验阶段,目标是在尽可能对吞吐量影响不大的前提下,实现在任意堆内存大小下都可以把垃圾收集的停顿时间限制在十毫秒以内的低延迟。 ZGC收集器是一款基于Region内存布局的,(暂时)不设分代的,使用了读屏障、染色指针和内存多重映射等技术来实现可并发的标记-压缩算法的,以低延迟为首要目标的一款垃圾收集器。
|