jvm垃圾回收器

发布时间:2023年12月31日

经典垃圾收集器

虚拟机包含的所有收集器

img

上图展示了7种作用于不同分代的收集器,如果两个收集器之间存在连线,就说明它们可以搭配使用。

虚拟机所处的区域,则表示它是属于新生代收集器还是老年代收集器。Hotspot实现了如此多的收集器,正是因为目前并无完美的收集器出现,只是选择对具体应用最适合的收集器。

垃圾收集器分类

1. 串行垃圾回收器

串行垃圾回收器是 JVM 最简单、最基础的垃圾回收器。它只使用一个线程进行垃圾回收,并且在进行垃圾回收时会暂停所有的应用程序线程。这种垃圾回收器适用于小型应用程序,因为它能够快速回收内存并且具有较低的 CPU 开销。然而,由于它需要停止应用程序线程,因此不适用于大型应用程序。

2. 并行垃圾回收器

并行垃圾回收器使用多个线程进行垃圾回收,可以在一定程度上提高垃圾回收的速度。与串行垃圾回收器相比,它对应用程序的影响更小,因为垃圾回收和应用程序可以并行运行。然而,由于并行垃圾回收器需要使用多个线程,因此它可能会占用更多的 CPU 资源,这可能会影响应用程序的性能。

3. 并发标记清除垃圾回收器

并发标记清除垃圾回收器是一种并发垃圾回收器,它可以在应用程序运行时进行垃圾回收。它的工作原理是先标记所有的存活对象,然后清除未被标记的对象。由于垃圾回收和应用程序可以并行运行,因此并发标记清除垃圾回收器对应用程序的影响非常小。但是,由于它需要在标记对象时使用多个线程,因此它可能会占用更多的 CPU 资源,这可能会影响应用程序的性能。

1.serial收集器

单线程收集器说明会使用一个处理器或一条收集线程去完成垃圾收集工作,在进行垃圾收集的时候必须暂停所有工作线程

是hotpot运行在客户端模式喜爱的默认新生代收集器,简单高效,内存消耗最小

2.parNew收集器

是serial收集器是多线程并发版本,没有太大更新,主要运行在服务端模式下的虚拟器中,只有它能与cms垃圾收集器

配合使用,

3.Parallel Scavenge收集器

吞吐量 = 运行用户代码时间/运行用户代码时间+运行垃圾收集时间

Parallel Scavenge 垃圾回收器是一种并行的垃圾回收器,它被设计用于处理大量的垃圾数据,可以最大限度地利用多核 CPU 的性能。Parallel Scavenge 垃圾回收器主要用于高吞吐量的应用程序,例如 Web 应用程序或后端服务器。

Parallel Scavenge 垃圾回收器的工作原理是,将堆分成多个区域,并使用标记-复制算法来清理垃圾对象。Parallel Scavenge 垃圾回收器同时使用多个线程来处理垃圾回收,从而加速清理过程。

4.Serial Old 垃圾回收器

Serial Old 垃圾回收器是 Serial 垃圾回收器的老年代版本,它用于清理老年代中的垃圾对象。它与Serial垃圾回收器相同,也是单线程的,会暂停所有的 Java 线程来进行垃圾回收。由于它是单线程的,因此清理时间较长,会导致较长的停顿时间。Serial Old 垃圾回收器主要用于小型应用程序和测试环境

5. Parallel Old 垃圾回收器

Parallel Old 垃圾回收器是 Parallel Scavenge 垃圾回收器的老年代版本,它用于处理老年代中的大量垃圾数据。Parallel Old 垃圾回收器是一种并行的垃圾回收器,可以最大限度地利用多核 CPU 的性能。

Parallel Old 垃圾回收器的工作原理与 Parallel Scavenge 垃圾回收器类似,将堆分成多个区域,并使用标记-复制算法来清理垃圾对象。Parallel Old 垃圾回收器同时使用多个线程来处理垃圾回收,从而加速清理过程。

6. CMS 垃圾回收器

CMS 垃圾回收器是一种并发的垃圾回收器,它不会暂停所有的 Java 线程来进行垃圾回收,而是在应用程序运行时与垃圾回收同时进行。CMS 垃圾回收器主要用于响应时间要求严格的应用程序,例如 Web 应用程序或交易系统。

CMS 垃圾回收器的工作原理是,将堆分成多个区域,并使用标记-清除算法来清理垃圾对象。与其他垃圾回收器不同的是,CMS 垃圾回收器会在应用程序运行时与垃圾回收同时进行,而不是暂停所有的 Java 线程来进行垃圾回收。这意味着 CMS 垃圾回收器可以最大限度地减少垃圾回收的停顿时间。

工作的具体步骤如下:
  1. 初始标记(Initial Mark):在此阶段,GC 线程会暂停应用程序的执行,然后标记所有直接可达的对象,并记录它们的引用信息,以便在后续的标记过程中能够正确地处理它们。
  2. 并发标记(Concurrent Mark):在此阶段,GC 线程会启动并发标记线程来进行并发标记,遍历整个堆,标记所有与初始标记中直接可达的对象间接可达的对象。
  3. 重新标记(Remark):在此阶段,GC 线程会再次暂停应用程序的执行,重新遍历堆中所有被标记的对象,并标记那些在并发标记期间被修改或新增的对象。
  4. 并发清理(Concurrent Sweep):在此阶段,GC 线程会启动并发清理线程来进行并发清理,清理未被标记的垃圾对象,并回收堆内存。
存在问题

CMS 回收器可以在应用程序运行时进行垃圾回收,但是在回收过程中可能会出现“浮动垃圾”问题和内存碎片化问题。

浮动垃圾可能产生并发失败
在上述并发标记和并发清除过程中,应用程序在运行中同时在修改和使用对象,会产生新的垃圾。但是标记过程已经结束了,产生的垃圾不会在本次垃圾收集被回收,只好等待下次 GC 时再进行回收,这部分称为浮动垃圾。
由于垃圾收集阶段用户线程还在同步运行,就不能像其他收集器一样等待老年代几乎完全使用后再进行收集,必须预留一部分空间供并发收集时的应用程序运行使用。当这部分空间使用完毕后,新的对象已无法分配到内存,就会产生并发失败。这会导致虚拟机启动后备预案:冻结用户的所有线程,临时启用 Serial Old 收集器来进行老年代的收集

内存碎片
在 CMS 回收器中,由于采用了标记-清除算法,当进行清除操作时,只会回收已标记的内存块,因此会出现内存碎片问题。具体来说,CMS 回收器在进行并发清理操作时,只会回收那些已标记为垃圾的对象,而对于那些没有被标记为垃圾的对象,CMS 回收器不会处理,它们会留在堆中的任意位置,形成内存碎片。
由于内存碎片问题会导致内存空间的利用率下降,因此会影响应用程序的性能和稳定性。一方面,由于内存碎片导致内存空间无法被充分利用,因此 CMS 回收器可能需要频繁地触发 GC,以清理那些被浪费的内存空间,这样就会影响应用程序的吞吐量。另一方面,由于内存碎片导致内存空间不连续,因此在进行内存分配时,需要寻找足够大且连续的内存空间,这样就会导致内存分配效率下降,从而影响应用程序的响应时间。

为了解决内存碎片的问题,CMS 提供了下面两个参数来进行内存整理:
-XX:UseCMSCompactAtFullCollection 是一个布尔类型的参数,表示在 CMS 回收器执行 Full GC 操作时是否进行内存压缩。当该参数设置为 true 时,在进行 Full GC 操作时,CMS 回收器会自动启用内存压缩算法来整理内存碎片,从而提高内存的利用率和分配效率。
-XX:CMSFullGCBeforeCompaction 是一个整型参数,表示在 CMS 回收器执行多少次 Full GC 操作后进行一次内存压缩。当该参数设置为一个正整数时,CMS 回收器会在执行指定次数的 Full GC 操作后,自动启用内存压缩算法来整理内存碎片。通过调整该参数的值,可以控制内存压缩的频率,从而进一步优化内存管理效率。
需要注意的是,内存压缩算法会消耗一定的 CPU 和内存资源,因此在进行 Full GC 操作时启用内存压缩可能会导致应用程序的性能下降。因此,需要根据实际情况来调整相关参数,以取得最佳的性能表现。

7.G1 垃圾回收器

G1 垃圾回收器是一种面向服务端的垃圾回收器,它能够在保证较短停顿时间的同时,达到很高的吞吐量。G1 垃圾回收器将堆内存划分为多个大小相等的区域,每个区域可以是 Eden 区、Survivo 区或 Old 区。G1 垃圾回收器采用分代垃圾回收的思想,对于每个区域的垃圾回收采用标记-整理算法。

G1 垃圾回收器的优点在于,可以在一定程度上避免 Full GC,减少停顿时间。此外,G1 垃圾回收器还支持增量清理和并发清理,能够在保证较短停顿时间的同时,达到很高的吞吐量。

工作的具体步骤

  1. 初始标记(Initial Mark):在此阶段,GC 线程会暂停应用程序的执行,标记所有直接可达的对象,并记录它们的引用信息,以便在后续的标记过程中能够正确地处理它们。此阶段与 CMS 的初始标记类似。
  2. 并发标记(Concurrent Mark):在此阶段,GC 线程会启动并发标记线程来进行并发标记,遍历整个堆,标记所有与初始标记中直接可达的对象间接可达的对象。此阶段与 CMS 的并发标记类似。
  3. 最终标记(Final Mark):在此阶段,GC 线程会暂停应用程序的执行,再次遍历堆中所有被标记的对象,并标记那些在并发标记期间被修改或新增的对象,同时计算每个区域中的垃圾比例。
  4. 筛选回收(Live Data Counting and Evacuation):在此阶段,GC 线程会启动筛选回收线程,基于最终标记中的垃圾比例和空间利用率等信息,决定优先回收哪些区域,并将其内存中的存活对象转移到其他区域,以便后续的并发清理。
  5. 并发清理(Concurrent Clean-up):在此阶段,GC 线程会启动并发清理线程来进行并发清理,清理未被标记的垃圾对象,并回收堆内存
文章来源:https://blog.csdn.net/m0_74347016/article/details/135313494
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。