【JVM】十五、详解ParNew垃圾回收器的工作原理
我们将深入研究常见的新生代和老年代垃圾回收器的运行原理,并探讨常见的垃圾回收参数设置方法。同时,结合案例,我们将研究在上线新系统时,如何通过预估手段和方法提前对系统的垃圾回收参数进行合理设置,以提高系统性能。
1、前文回顾
在之前的文章中,我们已经详细梳理了JVM的核心运行原理,相信大家现在对以下几个方面有了更深入的了解:
- 对象的分配过程:对象是如何在新生代进行分配的,以及何时会触发Minor GC。
- 内存检查:在触发Minor GC之前,如何检查老年代可用内存大小和新生代对象大小,以及历次Minor GC之后升入老年代的平均对象大小。
- 触发机制:在什么情况下,Minor GC之前会提前触发Full GC,以及何时会直接触发Minor GC。
- 对象晋升:在Minor GC之后,有哪几种情况会导致对象进入老年代。
- 垃圾回收概念:大家也对垃圾回收器、垃病回收线程、垃圾回收算法之间的关系有了初步了解,包括垃圾回收过程中的“Stop the World”现象及其对系统性能的影响。
接下来,我们将深入研究常见的新生代和老年代垃圾回收器的运行原理,并探讨常见的垃圾回收参数设置方法。同时,结合案例,我们将研究在上线新系统时,如何通过预估手段和方法提前对系统的垃圾回收参数进行合理设置,以提高系统性能。
2、新生代垃圾回收的首选:ParNew
在过往的多年里,如果没有最新的G1垃圾回收器,通常在线系统都是使用ParNew垃圾回收器作为新生代的垃圾回收器。然而,即便现在有了G1,许多在线系统仍然选择使用ParNew。
一般来说,运行在服务器上的Java系统,都可以充分利用服务器的多核CPU的优势。因此,我们可以想象,如果你的服务器是4核CPU,如果在进行新生代垃圾回收时,仅仅使用单线程进行垃圾回收,是否会导致无法充分利用CPU资源?如下图:
在垃圾回收过程中,如果将所有系统程序的工作线程全部暂停,仅运行一个垃圾回收线程,那么4核CPU的资源将无法得到充分利用。理论上,4核CPU可以支持4个垃圾回收线程并行执行,从而提升性能。
在这种情况下,新生代的ParNew垃圾回收器采用了多线程垃圾回收机制,而另一种Serial垃圾回收器则采用了单线程垃圾回收。它们之间的主要区别在于使用单线程还是多线程进行垃圾回收,但垃圾回收算法本身是相同的。
当ParNew垃圾回收器在适当的时机执行Minor GC时,它会暂停系统程序的工作线程,阻止程序继续运行和创建新的对象。然后,它使用多个垃圾回收线程进行垃圾回收,其回收机制和算法与之前所述相同。

3、如何配置ParNew垃圾回收器优化线上系统?
在启动线上系统时,我们有多种方式来设置JVM参数。例如,在Eclipse或IntelliJ IDEA中,我们可以设置Debug JVM Arguments;使用“java -jar”命令启动时,可以直接在后面加上JVM参数。当我们将应用部署到Tomcat时,可以在Tomcat的catalina.sh中设定Tomcat的JVM参数。同样,如果使用Spring Boot,也可以在启动时指定JVM参数。
那么,如果我们需要在启动系统时指定使用ParNew垃圾回收器,应该使用什么参数呢?其实非常简单,只需要使用“-XX:+UseParNewGC”选项。只要加入这个选项,JVM启动后对新生代进行垃圾回收的任务就交给了ParNew垃圾回收器。
至于Minor GC的触发时机、检查机制,包括垃圾回收的具体过程,以及对象升入老年代的机制,这些都是我们之前讨论过的原理。但是,我们需要知道的是,ParNew会使用多个线程来进行垃圾回收,这是其一个显著的特点。
4、了解ParNew默认线程数
在现代的服务器部署中,多核CPU的使用已经成为了标准配置。为了在垃圾回收过程中充分利用这些多核CPU的资源,当我们选择使用ParNew垃圾回收器时,系统会默认将其垃圾回收线程的数量设置为与CPU的核数相同。
例如,如果我们的服务器配备了4核、8核或16核的CPU,那么ParNew垃圾回收器的线程数量将分别被设置为4个、8个和16个。这样的设置可以确保垃圾回收过程能够充分并行,提高处理效率。
通常情况下,我们无需手动调整这个线程数量,因为与CPU核数相同的线程数量已经能够实现高效的并行处理。从下面的示意图中,我们可以看到,每个线程都通过一个独立的CPU进行运行,实现了资源的最大化利用。

在调整JVM的垃圾回收线程数量时,您确实可以自定义ParNew的垃圾回收线程数量。这是通过使用"-XX:ParallelGCThreads"参数来实现的,该参数允许您设置用于执行垃圾回收的线程数。
然而,我们通常不建议随意修改这个参数。因为不恰当的调整可能导致性能问题,甚至可能对系统稳定性造成影响。
5、本文总结
这篇文章篇幅不长,主要介绍一下ParNew垃圾回收器,其实垃圾回收器的工作原理之前上周就全部介绍过了,本文主要就是对ParNew垃圾回收器本身的多线程原理和相关的参数做一些说明。