java垃圾收集器详解

垃圾收集器

Serial

Serial收集器是Java虚拟机中最基本的垃圾回收(GC)收集器之一,主要特点是单线程的垃圾回收。虽然它只使用一个线程进行垃圾回收,但Serial收集器在单CPU环境或者小内存资源的情况下表现得相当高效。由于其单线程的特性,Serial收集器在执行垃圾回收时,会触发“Stop-The-World”(STW),即在垃圾回收过程中会暂停其他所有的应用线程。

Serial 收集器的特点

  1. 单线程:Serial收集器仅使用一个线程执行垃圾回收任务。这意味着它相比多线程收集器在资源占用上更少。
  2. 简单而高效:在单CPU或者内存较小的环境中,由于没有线程切换的开销,Serial收集器在这类环境下非常高效。
  3. Stop-The-World:在Serial收集器执行垃圾回收过程中,必须暂停其他所有工作线程,直到垃圾回收完成。

Serial 收集器的工作原理

Parallel Old收集器是Java虚拟机中的一种老年代垃圾收集器,它是Parallel Scavenge收集器的老年代版本。与Parallel Scavenge收集器一样,Parallel Old收集器也以提高吞吐量为目标,适用于后台运行的大型应用,如科学计算和大数据处理。

Parallel Old 收集器的主要特点

  1. 多线程收集:Parallel Old收集器采用多线程来执行垃圾回收任务,能够在多核处理器上充分利用计算资源,提高垃圾回收的效率。
  2. 高吞吐量优先:与Parallel Scavenge收集器类似,Parallel Old收集器的设计目标也是达到高吞吐量。它更适合处理大型应用,能够在保证吞吐量的同时,尽量减少垃圾收集的停顿时间。
  3. 标记-整理算法:Parallel Old收集器同样使用标记-整理算法来进行垃圾回收。该算法能够防止内存碎片化,使得内存空间的利用更加高效。

Parallel Old 收集器的工作原理

Parallel Old收集器的工作原理与Serial Old收集器类似,但是它是多线程执行的。其工作过程可以简要概括为以下几个步骤:

  1. 初始标记(Initial Mark):标记所有直接与GC Roots相连的对象,这一步需要停止所有的工作线程。
  2. 并行标记(Concurrent Marking):并行地遍历对象图,标记所有可达的对象。与标记阶段并行执行,不需要暂停应用线程。
  3. 重新标记(Remark):在并发标记过程结束后,需要对标记过程中发生变化的对象进行重新标记。这一步需要暂停所有的工作线程。
  4. 整理(Compaction):将所有存活的对象压缩到内存的一端,清理掉未使用的内存空间,防止内存碎片化。

Parallel Old 收集器的适用场景

由于Parallel Old收集器的设计目标是高吞吐量,它特别适合用于需要长时间运行的大型应用,如后台处理、科学计算和大数据处理等场景。它在处理大型内存和高并发的情况下表现出色,能够在保证吞吐量的同时,尽可能减少垃圾收集的停顿时间。

总结

Parallel Old收集器是Java虚拟机中一种高效的老年代垃圾收集器,适用于需要高吞吐量和长时间运行的大型应用场景。它利用多线程并行处理垃圾回收任务,能够充分利用多核处理器的计算资源,提高垃圾回收的效率。选择合适的垃圾收集器需要根据应用的需求和特性来进行评估,Parallel Old收集器是在高吞吐量要求下的一个很好的选择。

Serial收集器工作在新生代使用标记-复制(Mark-Copy)算法,在老年代使用标记-清除-整理(Mark-Sweep-Compact)算法。其垃圾回收过程可分为以下几个阶段:

  1. 标记:首先标记出所有从GC Roots可达的对象。GC Roots包括在执行方法中的局部变量和输入参数、活动线程、静态字段等。
  2. 清除:在老年代,清除阶段会移除所有不可达的对象。
  3. 复制:在新生代,不是简单地清除不可达对象,而是将存活的对象复制到另一个区域(一般是从Eden区和一个Survivor区复制到另一个Survivor区),这样做可以快速清理整个Eden和一个Survivor区。
  4. 整理:在老年代的最后阶段,为了防止内存碎片化,垃圾收集器会进行内存整理,将所有存活的对象向一端移动,清理出连续的空闲内存。

Serial 收集器的适用场景

由于其简单和高效的特性,Serial收集器适合在以下场景中使用:

  • 客户端模式:如桌面应用程序,客户端应用程序往往资源有限,且对实时性要求不高。
  • 小内存需求的环境:在内存较小的环境下,Serial收集器由于其低资源消耗的优势,可以有效运行。

总结

虽然Serial收集器在多核处理器和要求高响应时间的应用程序中可能不是最佳选择,但其在特定条件下的高效性使其仍然在Java虚拟机中保有一席之地。对于小型或资源受限的应用环境,或是在开发和测试环境中,使用Serial收集器可以简化虚拟机的性能调优工作,因为其行为相对容易预测。

ParNew

ParNew收集器可以被视为Serial收集器的多线程版本。它主要用于新生代的垃圾收集,并且与Serial收集器类似,采用了标记-复制(Mark-Copy)算法。不同的是,ParNew收集器使用多线程进行垃圾回收,因此在多核处理器上表现得更为出色。这使得ParNew收集器成为许多服务器端应用的首选,特别是在与老年代的并发收集器(如CMS)配合使用时。

ParNew 收集器的特点

  1. 多线程:ParNew是一个多线程的收集器,能够同时利用多个CPU核心进行垃圾回收,从而减少垃圾回收的停顿时间。
  2. Stop-The-World:尽管使用多线程进行垃圾回收,ParNew收集器仍然会触发Stop-The-World事件。所有用户线程都会在垃圾收集期间暂停,直到收集结束。
  3. 新生代收集器:ParNew只用于新生代的垃圾回收。新生代中存活对象较少,通过多线程复制活动对象到存活区,可以快速完成收集,有效减少垃圾收集时间。
  4. 与CMS的搭配:ParNew收集器经常与老年代的CMS(Concurrent Mark-Sweep)收集器配合使用,形成一套高效的垃圾回收策略,尤其适用于需要低停顿时间的Web服务器环境。

ParNew 收集器的工作原理

ParNew收集器的工作原理基本与Serial收集器相同,但它通过使用多个线程来提高效率。收集过程分为以下几个阶段:

  1. 标记:并行地标记所有从GC Roots可达的对象。
  2. 复制:将所有存活的对象从一个区域复制到另一个区域。在新生代中,这通常意味着从Eden区和一个Survivor区复制到另一个Survivor区。通过多线程执行这一步,大大减少了复制所需的时间。
  3. 清理:完成复制后,清理原来的Eden区和Survivor区,为下一轮新对象分配做准备。

ParNew 收集器的适用场景和限制

适用场景

  • 多核服务器环境:在多核处理器上,ParNew能够利用额外的核心减少垃圾收集的停顿时间,适合需要快速响应的服务端应用。
  • 与CMS配合使用:在需要减少垃圾收集停顿时间的同时,处理大量老年代内存的应用中,ParNew与CMS的组合提供了一个不错的解决方案。

限制

  • 资源消耗:由于使用多线程,ParNew在垃圾回收时会占用更多CPU资源。在资源受限的环境下或当CPU负载已经很高时,使用ParNew可能会影响应用程序的性能。
  • Stop-The-World事件:尽管使用了多线程,ParNew仍然需要在垃圾回收时暂停所有应用线程,这可能对实时性要求极高的应用造成影响。

总结

ParNew收集器是一个在多核环境下表现良好的新生代垃圾回收器,尤其适合与CMS等老年代收集器配合使用,以达到在保持应用响应性的同时处理大量内存的需求。然而,需要根据具体的应用场景和需求来选择合适的垃圾收集器。

Parallel Scavenge


Parallel Scavenge收集器是一种新生代垃圾收集器,使用多线程和标记-复制算法进行垃圾回收,与ParNew收集器相似。它的主要设计目标是达到一个可控制的吞吐量(Throughput),适用于在后台运行的科学计算或者大数据处理等场合,其中更重视高吞吐量而不是最短停顿时间。

Parallel Scavenge收集器的主要特点

  1. 多线程收集:Parallel Scavenge收集器采用多线程来进行垃圾回收,能够在多核心处理器上发挥高效的垃圾收集性能。
  2. 高吞吐量优先:Parallel Scavenge收集器的设计目标是达到较高的吞吐量。吞吐量是指CPU用于运行用户代码的时间与CPU总消耗时间的比值(即用户时间 / (用户时间 + 垃圾收集时间))。适合需要长时间运行的应用,这些应用可以承受较长的垃圾收集停顿。
  3. 自适应调节策略:这个收集器配备了一个自适应的调节系统(-XX:+UseAdaptiveSizePolicy),这个系统可以自动调整Java堆中各个区域(Eden区、Survivor区和老年代)的大小以及相应的GC参数,目的是最大化吞吐量并满足指定的暂停时间目标。

Parallel Scavenge收集器的工作原理

Parallel Scavenge收集器在新生代采用并行的标记-复制算法:

  1. 标记:并行地标记所有从GC Roots可达的对象。
  2. 复制:将存活的对象复制到另一块未被使用的内存区域。在复制过程中,收集器会暂停所有应用线程(Stop-The-World),使用多个线程来加速复制和清除过程。
  3. 回收:完成复制后,原来的内存区域将被清空,为下一轮的对象分配做准备。

Parallel Scavenge收集器的适用场景

由于Parallel Scavenge收集器的设计目标是高吞吐量,它特别适合在多核心环境中处理批处理任务,如大数据处理、科学计算和后台处理等应用场景。这些应用通常不需要快速响应用户交互,而更关心总体运行时间。

与其他收集器的比较

  1. 与ParNew的比较:虽然ParNew也是一种新生代收集器,但它通常与老年代的CMS收集器配合使用,以减少应用的停顿时间。相比之下,Parallel Scavenge更侧重于提高吞吐量。
  2. 与Serial收集器比较:Parallel Scavenge是Serial收集器的多线程版本,能够更好地利用现代多核处理器的计算资源。
  3. 与G1收集器比较:G1收集器是一种更为现代的垃圾收集器,设计用于替代CMS,以及在更大的Java堆上提供更好的性能。G1收集器通过将堆划分为多个区域并在这些区域上并行和并发地执行垃圾回收,从而既优化了停顿时间也提高了吞吐量。

这是 JDK1.8 默认收集器

使用 java -XX:+PrintCommandLineFlags -version 命令查看

-XX:InitialHeapSize=262921408 -XX:MaxHeapSize=4206742528 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC
java version "1.8.0_211"
Java(TM) SE Runtime Environment (build 1.8.0_211-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.211-b12, mixed mode)

JDK1.8 默认使用的是 Parallel Scavenge + Parallel Old,如果指定了-XX:+UseParallelGC 参数,则默认指定了-XX:+UseParallelOldGC,可以使用-XX:-UseParallelOldGC 来禁用该功能

总结

Parallel Scavenge收集器是一个高效的新生代垃圾收集器,优先考虑高吞吐量,适合长时间运行的、不太关心响应速度的应用。它的自适应调节策略也使得它在多种场景下都能维持良好的性能表现。选择合适的垃圾收集器需要考虑应用的具体需求和工作负载特性。

Serial Old

Serial Old收集器是Java虚拟机中的一种老年代垃圾收集器,它是Serial收集器的老年代版本。这个收集器同样是一个单线程的收集器,使用标记-整理(Mark-Compact)算法来进行垃圾回收。由于其单线程的特性,它在垃圾回收时同样会引发“Stop-The-World”(STW)事件,即所有的应用线程都会在垃圾回收过程中被暂停。

Serial Old 收集器的特点

  1. 单线程:和Serial收集器一样,Serial Old是一个单线程的垃圾收集器,不需要处理线程间的同步问题,这在单核处理器或者小内存的环境中可以是一个优点,因为它避免了线程切换的开销。
  2. Stop-The-World:在Serial Old收集器执行垃圾回收过程中,需要暂停所有工作线程,直到垃圾回收完毕。这种暂停可能导致应用的停顿时间较长。
  3. 标记-整理算法:使用标记-整理算法可以防止内存碎片化。首先标记出所有从GC Roots可达的对象,然后将所有存活的对象移向一端,最后清理掉端边界以外的内存。

Serial Old 收集器的工作原理

Serial Old的工作机制可以分为几个步骤:

  1. 初始标记(Initial Mark):标记所有直接与GC Roots相连的对象,这一步需要停止所有的工作线程。
  2. 根枚举(Root Scanning):遍历GC Roots,标记所有可达的对象。由于是单线程操作,这一步骤的速度较慢。
  3. 标记过程(Marking):完成对所有可达对象的标记。这一步会递归地标记所有从根节点开始可达的对象。
  4. 整理(Compaction):将所有存活的对象压缩到内存的一端,清理掉未使用的内存空间,这样做有助于防止内存碎片化,并且简化了内存分配策略,因为JVM可以简单地增长末端指针来分配新对象。

Serial Old 收集器的适用场景

由于Serial Old收集器的设计并不支持多核处理器的并行处理能力,它主要适用于以下几种情况:

  • 单核处理器:在单核处理器或者计算资源非常有限的环境中,单线程的收集器可能因为没有多线程的额外开销而更有效。
  • 开发和测试环境:在开发和测试环境中,使用Serial Old收集器可以简化问题的复现,因为它的行为相对可预测,且没有并行处理的复杂性。
  • 与其他收集器的后备选项:在某些JVM实现中,Serial Old收集器也可以作为CMS收集器的后备垃圾收集器,用于在CMS收集器运行失败时进行老年代的垃圾回收。

总结

Serial Old收集器是一个比较传统的垃圾回收方式,适用于资源有限或单核环境。虽然它的垃圾收集过程中应用的停顿时间较长,但其简单性和避免内存碎片化的能力使得它在特定场景下仍然有其使用价值。

Parallel Old

Parallel Old收集器是Java虚拟机中的一种老年代垃圾收集器,它是Parallel Scavenge收集器的老年代版本。与Parallel Scavenge收集器一样,Parallel Old收集器也以提高吞吐量为目标,适用于后台运行的大型应用,如科学计算和大数据处理。

Parallel Old 收集器的主要特点

  1. 多线程收集:Parallel Old收集器采用多线程来执行垃圾回收任务,能够在多核处理器上充分利用计算资源,提高垃圾回收的效率。
  2. 高吞吐量优先:与Parallel Scavenge收集器类似,Parallel Old收集器的设计目标也是达到高吞吐量。它更适合处理大型应用,能够在保证吞吐量的同时,尽量减少垃圾收集的停顿时间。
  3. 标记-整理算法:Parallel Old收集器同样使用标记-整理算法来进行垃圾回收。该算法能够防止内存碎片化,使得内存空间的利用更加高效。

Parallel Old 收集器的工作原理

Parallel Old收集器的工作原理与Serial Old收集器类似,但是它是多线程执行的。其工作过程可以简要概括为以下几个步骤:

  1. 初始标记(Initial Mark):标记所有直接与GC Roots相连的对象,这一步需要停止所有的工作线程。
  2. 并行标记(Concurrent Marking):并行地遍历对象图,标记所有可达的对象。与标记阶段并行执行,不需要暂停应用线程。
  3. 重新标记(Remark):在并发标记过程结束后,需要对标记过程中发生变化的对象进行重新标记。这一步需要暂停所有的工作线程。
  4. 整理(Compaction):将所有存活的对象压缩到内存的一端,清理掉未使用的内存空间,防止内存碎片化。

Parallel Old 收集器的适用场景

由于Parallel Old收集器的设计目标是高吞吐量,它特别适合用于需要长时间运行的大型应用,如后台处理、科学计算和大数据处理等场景。它在处理大型内存和高并发的情况下表现出色,能够在保证吞吐量的同时,尽可能减少垃圾收集的停顿时间。

总结

Parallel Old收集器是Java虚拟机中一种高效的老年代垃圾收集器,适用于需要高吞吐量和长时间运行的大型应用场景。它利用多线程并行处理垃圾回收任务,能够充分利用多核处理器的计算资源,提高垃圾回收的效率。选择合适的垃圾收集器需要根据应用的需求和特性来进行评估,Parallel Old收集器是在高吞吐量要求下的一个很好的选择。

CMS

CMS(Concurrent Mark-Sweep)收集器是Java虚拟机中的一种老年代垃圾收集器,其设计目标是在尽可能减少应用程序停顿时间的前提下,实现高吞吐量的垃圾收集。CMS收集器主要解决了长时间停顿时间的问题,适用于对停顿时间要求较高的应用场景,如Web应用、电子商务系统等。

CMS 收集器的主要特点

  1. 并发标记:CMS收集器采用了并发标记(Concurrent Mark)的方式来标记垃圾对象,这意味着垃圾收集过程与应用程序线程同时进行,减少了停顿时间。在标记阶段,CMS会在多个线程的情况下,并发地遍历对象图,并标记出存活对象。
  2. 并发清除:在标记阶段完成后,CMS收集器会进行并发清除(Concurrent Sweep),清理出被标记为垃圾的对象。与标记阶段类似,清除阶段也是在应用程序线程运行的同时进行的。
  3. 空闲时收集:CMS收集器的垃圾收集过程一般会在应用程序的空闲时间进行,这样可以最大限度地减少对应用程序的影响。
  4. 低停顿时间:由于CMS收集器的标记和清除过程是与应用程序并发进行的,因此它能够在较短的停顿时间内完成垃圾收集,适用于对停顿时间要求较高的应用场景。

CMS 收集器的工作原理

CMS收集器的工作过程可以分为以下几个阶段:

  1. 初始标记阶段(Initial Mark):暂停所有应用线程,标记出GC Roots直接关联的对象,这个阶段的停顿时间非常短。
  2. 并发标记阶段(Concurrent Mark):并发地遍历对象图,标记出所有存活的对象。在这个阶段,应用程序线程和垃圾收集线程可以同时运行。
  3. 重新标记阶段(Remark):暂停所有应用线程,对在并发标记阶段发生变化的对象进行重新标记。这个阶段的停顿时间较短,但会比初始标记阶段略长一些。
  4. 并发清除阶段(Concurrent Sweep):与应用程序线程并发进行,清除出被标记为垃圾的对象。这个阶段的停顿时间较短。

CMS 收集器的适用场景

CMS收集器适用于以下场景:

  • 对停顿时间要求高:CMS收集器能够在较短的停顿时间内完成垃圾收集,适合对停顿时间要求较高的应用场景,如Web应用、电子商务系统等。
  • 多核处理器:CMS收集器可以利用多核处理器的优势,并发执行标记和清除阶段,提高垃圾收集的效率。
  • 老年代垃圾收集:CMS收集器主要用于老年代的垃圾收集,对于大型内存和老年代对象较多的应用场景表现较好。

CMS 收集器的局限性

尽管CMS收集器具有很多优点,但也存在一些局限性:

  • 内存碎片化问题:CMS收集器在清除阶段是采用标记-清除算法,容易产生内存碎片,导致长期运行的应用程序可能会出现内存分配失败的问题。
  • 并发执行对系统资源的影响:并发执行垃圾收集会占用一定的系统资源,可能会影响应用程序的吞吐量。
  • 并发标记的阶段可能会导致内存溢出:如果并发标记的阶段耗时过长,可能会导致老年代空间不足,从而触发Full GC,导致应用程序的停顿时间较长。

总结

CMS收集器是一种专注于减少停顿时间的老年代垃圾收集器,适用于对停顿时间要求较高的应用场景。它通过并发执行标记和清除阶段,尽可能减少垃圾收集对应用程序的影响,提高了应用程序的响应性。然而,CMS收集器也存在一些局限性,需要根据具体的应用需求来选择合适的垃圾收集器。

G1

G1(Garbage-First)收集器是Java虚拟机中的一个高级垃圾回收器,设计用于替换CMS收集器,提供更高的预测性能以减少应用停顿时间。G1收集器特别适用于具有大内存容量和多核处理器的系统,在这些系统上,它可以高效地管理堆内存,同时提供较低的垃圾收集停顿时间。

G1 收集器的主要特点

  1. 区域划分:G1收集器将整个Java堆划分为多个大小相同的独立区域(Region),这些区域可以是Eden区、Survivor区或Old区。这种划分使得G1能够更灵活地进行垃圾回收,只处理那些包含垃圾最多的区域。
  2. 并发和并行执行:G1收集器结合了并发和并行的垃圾回收技术,能够在应用程序运行时并发地执行某些垃圾回收阶段,同时利用多线程进行并行垃圾回收以提高效率。
  3. 预测性停顿时间模型:G1收集器可以设置期望的停顿时间目标(例如50毫秒),收集器会自动调整其工作方式来尽量满足这些停顿时间目标。
  4. 增量处理:G1收集器采用增量方式清理堆内存,逐步清理垃圾,从而避免在整个堆内存上进行全面清理,减少单次垃圾收集的停顿时间。

G1 收集器的工作原理

G1收集器的垃圾回收过程包括几个阶段:

  1. 初始标记(Initial Mark):此阶段与应用程序线程同时运行,但需要在开始时短暂停顿来标记所有从GC Roots直接可达的活动对象。
  2. 并发标记(Concurrent Mark):在此阶段,G1收集器遍历堆中的对象图,标记所有存活的对象,此阶段与应用程序并发执行,减少了停顿时间。
  3. 最终标记(Final Mark):此阶段完成剩余的标记工作,处理自并发标记以来发生变化的区域。这一阶段通常需要短暂的停顿。
  4. 筛选回收(Evacuation):在这一阶段,G1收集器对内存中的区域进行清理,优先处理那些垃圾最多的区域。这一阶段是并行的,并且可能需要停顿应用程序线程。

G1 收集器的适用场景

G1收集器适用于以下场景:

  • 大内存应用:对于需要大量内存的应用程序,G1能够更有效地管理堆,并减少长时间的垃圾回收停顿。
  • 需要低延迟的应用:如果应用需要低延迟,G1收集器能通过预测性停顿时间模型来优化垃圾回收过程,满足应用对响应时间的要求。
  • 多核服务器:由于G1能够进行并行和并发垃圾回收,它非常适合在多核服务器上运行,可以有效利用服务器的计算资源。

G1 收集器的局限性

尽管G1收集器提供了许多优势,它仍有一些局限性:

  • 资源消耗

:在并发标记阶段,G1收集器可能会消耗更多的CPU资源,因为它需要在应用程序运行时进行垃圾标记。

  • 复杂性:G1收集器的管理和调优相比其他收集器更为复杂,需要根据应用的具体需求调整多个参数以达到最优性能。

总结

G1收集器是Java平台中高级的垃圾回收技术,适用于需要处理大内存、要求低延迟并且运行在多核硬件上的应用。它通过划分内存区域并采用增量清理策略,提高了垃圾回收的效率,并能够相对控制停顿时间,满足现代应用的需求。选择G1收集器可以帮助开发者在维持应用性能的同时,确保系统的稳定性和响应速度。

并发与并行

在Java虚拟机(JVM)中,垃圾回收(GC)是一个重要过程,用于释放不再使用的对象所占用的内存空间,以保持应用程序的健康运行。在讨论垃圾回收时,"并发"和"并行"这两个术语经常出现,它们描述的是垃圾回收任务执行的方式,影响着垃圾回收的效率和应用程序的性能表现。

并行垃圾回收(Parallel Garbage Collection)

并行垃圾回收指的是多个垃圾回收线程同时工作,以缩短垃圾回收所需的总时间。在并行回收中,所有或部分垃圾回收工作同时进行,但这通常会导致应用程序的所有线程暂停,直到垃圾回收任务完成。这种暂停被称为"Stop-The-World"(STW)事件。

特点

  • 效率高:多个处理器或核心被同时利用,可以更快地完成内存清理。
  • 停顿明显:由于所有用户线程都被暂停,因此在垃圾回收期间,应用的响应时间和实时性会受到影响。

示例

Java的Parallel GC就是一个典型的并行收集器,它在新生代使用并行的标记-复制(mark-copy)算法,在老年代使用并行的标记-清理-整理(mark-sweep-compact)算法。

并发垃圾回收(Concurrent Garbage Collection)

并发垃圾回收指的是垃圾回收任务在应用程序线程后台运行,与应用程序线程同时执行。这种方式的目标是减少垃圾回收对应用程序运行的干扰,特别是减少停顿时间。

特点

  • 低停顿:应用程序仍然可以处理用户请求,响应性和实时性较好。
  • 资源竞争:垃圾回收线程与应用程序线程可能会竞争计算资源,可能导致应用程序运行速度略有降低。
  • 复杂性高:并发执行的管理和调优比并行执行更为复杂。

示例

CMS(Concurrent Mark-Sweep)收集器和G1(Garbage First)收集器都是支持并发执行的垃圾回收器。它们在执行大部分垃圾回收任务时不需要暂停应用线程,但在某些阶段仍然需要短暂的STW停顿。

并发与并行的选择

选择并行还是并发垃圾回收,主要取决于应用的需求:

  • 并行垃圾回收适合于批处理和后台处理等对停顿时间不敏感的场景,能够最大化吞吐量。
  • 并发垃圾回收适合于交互式应用和实时系统,这些系统对停顿时间非常敏感。

在实际应用中,开发者需要根据应用的具体情况(如可用核心数、堆大小、应用的响应时间要求等)来选择最合适的垃圾回收策略。随着技术的发展,新一代垃圾回收器如G1和即将到来的ZGC(Z Garbage Collector)和Shenandoah GC,都在尝试将并行和并发优势结合起来,以提供更低的停顿时间同时保持高吞吐量,适应更广泛的应用场景。

ZGC

ZGC(Z Garbage Collector)是一种由Oracle开发的垃圾收集器,专门针对Java虚拟机(JVM)而设计。它被设计用于处理大内存堆和低停顿时间的情况,旨在提供高性能和可预测的垃圾收集。

与 CMS 中的 ParNew 和 G1 类似,ZGC 也采用标记-复制算法,不过 ZGC 对该算法做了重大改进。

ZGC 可以将暂停时间控制在几毫秒以内,且暂停时间不受堆内存大小的影响,出现 Stop The World 的情况会更少,但代价是牺牲了一些吞吐量。ZGC 最大支持 16TB 的堆内存。

ZGC 在 Java11 中引入,处于试验阶段。经过多个版本的迭代,不断的完善和修复问题,ZGC 在 Java15 已经可以正式使用了。

不过,默认的垃圾回收器依然是 G1。你可以通过下面的参数启用 ZGC:

java -XX:+UseZGC className

在 Java21 中,引入了分代 ZGC,暂停时间可以缩短到 1 毫秒以内。

你可以通过下面的参数启用分代 ZGC:

java -XX:+UseZGC -XX:+ZGenerational className

关于 ZGC 收集器的详细介绍推荐阅读美团技术团队的 新一代垃圾回收器 ZGC 的探索与实践 这篇文章。

以下是ZGC收集器的一些特点介绍:

1. 低停顿时间:ZGC的最主要特点之一就是其低停顿时间。在现代应用程序中,尤其是对于需要处理大量数据的应用,长时间的垃圾收集暂停会导致严重的性能问题。ZGC通过实现并发的垃圾收集算法,尽可能减少了应用程序的停顿时间,使得应用在执行垃圾收集时的暂停时间保持在几毫秒到几十毫秒之间。

2. 大内存堆支持:随着应用程序的规模不断增大,对于大内存堆的支持变得尤为重要。ZGC专门针对TB级别的内存堆进行了优化,使得它能够在非常大的堆上进行高效的垃圾收集。这使得ZGC成为处理大型Java应用程序的理想选择。

3. 透明的并发收集:ZGC执行垃圾收集时尽量避免停止应用程序的运行。它采用了一系列并发收集技术,如压缩指针、染色指针和读屏障等,以实现与应用程序并发运行。这意味着即使在执行垃圾收集的同时,应用程序也可以继续响应用户请求,从而提高了应用程序的响应性和吞吐量。

4. 可预测的性能:ZGC通过控制并发收集的阶段和与应用程序并发运行的方式,提供了可预测的性能。这意味着开发人员可以更好地了解应用程序在执行垃圾收集时的性能表现,从而更好地规划和优化应用程序的资源使用。

综上所述,ZGC是一种专门针对大内存堆和低停顿时间的Java垃圾收集器。其低停顿时间、对大内存堆的支持、透明的并发收集和可预测的性能使得它成为处理大型Java应用程序的理想选择。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/604507.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

鸿蒙开发全攻略:华为应用系统如何携手嵌入式技术开启新篇章~

鸿蒙操作系统是华为自主创新的成果,打破了传统操作系统的局限。通过结合嵌入式技术,鸿蒙实现了跨平台、跨设备的高度融合,提供了流畅、智能的体验。华为应用系统与嵌入式技术的结合,提升了性能,丰富了用户体验。鸿蒙与…

【stm-4】PWM驱动LED呼吸灯 PWM驱动舵机PWM驱动直流电机

1.PWM驱动LED呼吸灯 void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); //结构体初始化输出比较单元 void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef*…

RabbitMQ的五种模式

一、简单模式 简单模式(Simple):一个生产者,一个消费者 package com.qiangesoft.rabbitmq.mode.simple;import lombok.extern.slf4j.Slf4j; import org.springframework.amqp.rabbit.annotation.Queue; import org.springframe…

mysql集群cluster引擎在写入数据时报错 (1114, “The table ‘ads‘ is full“)

问题描述:mysql集群在写入数据时,出现上述报错 问题原因:表数据已满,一般是在集群的管理节点设置里面datamemory的值太小,当数据量超过该值时就会出现该问题 解决方案: 修改集群管理节点的config.ini里面…

JUC下的ScheduledThreadPoolExecutor详解

ScheduledThreadPoolExecutor是Java并发编程框架中一个强大且灵活的线程池实现,专为定时与周期性任务而设计。作为ThreadPoolExecutor的子类,它不仅继承了线程池管理的高效与灵活性,还内置了基于优先级队列的延迟任务调度机制,支持…

商务分析方法与工具(五):Python的趣味快捷-文件和文件夹操作自动化

Tips:"分享是快乐的源泉💧,在我的博客里,不仅有知识的海洋🌊,还有满满的正能量加持💪,快来和我一起分享这份快乐吧😊! 喜欢我的博客的话,记得…

pytest教程-41-钩子函数-pytest_runtest_teardown

领取资料,咨询答疑,请➕wei: June__Go 上一小节我们学习了pytest_runtest_call钩子函数的使用方法,本小节我们讲解一下pytest_runtest_teardown钩子函数的使用方法。 pytest_runtest_teardown 钩子函数在每个测试用例执行完成后被调用&…

游戏辅助 -- 三种分析角色坐标方法(CE、xdbg、龙龙遍历工具)

所用工具下载地址: https://pan.quark.cn/s/d54e7cdc55e6 在上次课程中,我们成功获取了人物对象的基址:[[[0xd75db8]1C]28],而人物血量的地址则是基址再加上偏移量278。 接下来,我们需要执行以下步骤来进一步操作&a…

JSP技术讲解

目录 1、JSP简介 2、JSP体验 3、JSP运行原理 4、JSP基本语法 5、JSP指令 6、JSP内置九大对象 7、JSP标签 8、JSP配置 9、JSP排错 10、总结 在前面的Servlet学习中发现Servlet本质是一个java程序,因此Servlet更加擅长编写程序的业务逻辑,而如果要…

BACnet到OPC UA的楼宇自动化系统与生产执行系统(MES)整合

在智能制造的浪潮下,一家位于深圳的精密电子制造企业面临着前所未有的挑战:如何高效地将楼宇自动化系统与生产执行系统(MES)整合,实现能源管理与生产流程的精细化控制。这家企业的楼宇控制系统使用的是BACnet协议&…

牛客NC97 字符串出现次数的TopK问题【中等 哈希+优先级队列 Java/Go】

题目 题目链接: https://www.nowcoder.com/practice/fd711bdfa0e840b381d7e1b82183b3ee 核心 哈希,优先级队列Java代码 import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返…

思维导图网页版哪个好?2024年值得推荐的8个在线思维导图软件!

思维导图如今已成为一种常用的工具,帮助我们清晰地组织和整理信息。随着科技的发展,思维导图的产品形态也经过多轮迭代,从最初的本地客户端过渡到基于云的 Web 端,各类网页版思维导图软件应运而生,它们方便快捷&#x…

【3dmax笔记】035: 车削修改器

一、车削修改器介绍 车削:图形通过绕轴旋转来创建三维效果。 开放的样条线,车削之后是面片。闭合的样条线,车削之后,是实体。 一、车削修改器实例 绘制高脚杯,首先在前视图绘制如下二维图形。 添加一个车削的修改器…

【Linux】shell基础,shell脚本

Shell Shell是一个用C语言编写的程序,接受用户输入的命令,并将其传递给操作系统内核执行。Shell还负责解释和执行命令、管理文件系统、控制进程,是用户使用Linux的桥梁。Shell既是一种命令语言,又是一种程序设计语言 Shell脚本 Sh…

HTML Audio标签src使用base64字符

源码&#xff1a; <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>Audio src base64</title> </head> <body><audio controls><source src"data:audio/mp3;base64,//OIxAAAAAAAAAA…

2.小土堆——tensorboard使用

1.tensorboard是啥&#xff1f; TensorBoard 是一个用于可视化 TensorFlow 训练过程和模型的工具。它可以帮助你以图形和图表的形式查看训练过程中的指标&#xff0c;比如损失和准确率的变化。你可以使用 TensorBoard 来监视模型的性能&#xff0c;并且更直观地理解模型的工作原…

Classifier guidance与Classifier free diffusion的简单理解

参考&#xff1a;Classifier Guidance 和 Classifier Free Guidance&#xff0c;一堆公式不如两行代码 - 蓟梗的文章 - 知乎 https://zhuanlan.zhihu.com/p/660518657 Classifier Guidance和Classifier-free Guidance 总结 - 走遍山水路的文章 - 知乎 https://zhuanlan.zhihu.c…

【雅思写作】Vince9120雅思小作文笔记——P1 Intro(前言)

文章目录 链接P1 Intro&#xff08;前言&#xff09;字数限制题型综述&#xff08;problem types overview&#xff09;1. **柱状图&#xff08;Bar Chart&#xff09;** - 描述不同类别在某个或多个变量上的数据量比较。2. **线图&#xff08;Line Graph&#xff09;** - 展示…

Lib city笔记:TrajectoryDataset

1 AbstractDataset 抽象类&#xff0c;所有数据集的基类 2 TrajectoryDataset 2.1 __init__ 2.2 get_data 2.3 cutter_filter 2.3.1 按照时间间隔切割 2.3.2 按照同一天切割 2.3.3 按照固定窗口长度切割 cut完的轨迹样子 每一个key是一个轨迹的id&#xff0c;对应的value内容…

SQL查询语句(三)范围查找关键字

在上一篇文章中&#xff0c;我们介绍了SQL语句中&#xff0c;逻辑关键字的作用&#xff0c;并举例演示了如何用逻辑关键字来组合WHERE子句。在文章的末尾我们提到了两个用于范围查找的关键字IN和BETWEEN。这两个关键字都可以与NOT关键字灵活组合&#xff0c;起到对字句结果取反…
最新文章