ParNew 回收器——并行回收

一 点睛

如果说 SerialGC 是年轻代中的单线程垃圾收集器,那么 ParNew 收集器则是 Serial 收集器的多线程版本。

Par 是 Parallel 的缩写,New:只能处理新生代

ParNew 收集器除了采用并行回收的方式执行内存回收外,两款垃圾收集器之间几乎没有任何区别。ParNew 收集器在年轻代中同样也是采用复制算法、 "stop-the-World" 机制。

ParNew 是很多 JVM 运行在 Server 模式下新生代的默认垃圾收集器。

  • 对于新生代,回收次数频繁,使用并行方式高效。

  • 对于老年代,回收次数少,使用串行方式节省资源。(CPU并行需要切换线程,串行可以省去切换线程的资源)

由于 ParNew 收集器是基于并行回收,那么是否可以断定 ParNew 收集器的回收效率在任何场景下都会比 Serial 收集器更高效?

  • ParNew 收集器运行在多 CPU 的环境下,由于可以充分利用多 CPU、多核心等物理硬件资源优势,可以更快速地完成垃圾收集,提升程序的吞吐量。

  • 但是在单个 CPU 的环境下,ParNew 收集器不比 Serial 收集器更高效。虽然 Serial 收集器是基于串行回收,但是由于 CPU 不需要频繁地做任务切换,因此可以有效避免多线程交互过程中产生的一些额外开销。

除 Serial 外,目前只有 ParNew GC 能与 CMS收集器配合工作。

二 参数配置

在程序中,开发人员可以通过选项"-XX:+UseParNewGC"手动指定使用 ParNew 收集器执行内存回收任务。它表示年轻代使用并行收集器,不影响老年代。

-XX:ParallelGCThreads 限制线程数量,默认开启和 CPU 核数相同的线程数。

三 实战

1 代码

/**
* -XX:+PrintCommandLineFlags
* -XX:+UseParNewGC:表明新生代使用ParNew GC
*/
public class GCUseTest {
    public static void main(String[] args) {
        ArrayList<byte[]> list = new ArrayList<>();
        while (true) {
            byte[] arr = new byte[100];
            list.add(arr);
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

2 测试

a 使用 -XX:+PrintCommandLineFlags -XX:+UseParNewGC 进行测试

在JDK 9的情况下会报错

D:\ProgramFiles\Java\jdk-9\bin\java.exe -XX:+PrintCommandLineFlags -XX:+UseParNewGC -javaagent:D:\ProgramFiles\JetBrains\IDEA\lib\idea_rt.jar=52919:D:\ProgramFiles\JetBrains\IDEA\bin -Dfile.encoding=UTF-8 -classpath E:\JVMDemo\out\production\chapter17 com.atguigu.java.GCUseTest

OpenJDK 64-Bit Server VM warning: Option UseParNewGC was deprecated in version 9.0 and will likely be removed in a future release.

It is not possible to combine the ParNew young collector with any collector other than CMS.

Error: Could not create the Java Virtual Machine.

Error: A fatal exception has occurred. Program will exit.

在JDK 8下测试结果如下

D:\ProgramFiles\Java\jdk1.8.0_251\bin\java.exe -XX:+PrintCommandLineFlags -XX:+UseParNewGC -javaagent:D:\ProgramFiles\JetBrains\IDEA\lib\idea_rt.jar=53065:D:\ProgramFiles\JetBrains\IDEA\bin -Dfile.encoding=UTF-8 -classpath D:\ProgramFiles\Java\jdk1.8.0_251\lib\ant-javafx.jar;D:\ProgramFiles\Java\jdk1.8.0_251\lib\dt.jar;D:\ProgramFiles\Java\jdk1.8.0_251\lib\javafx-mx.jar;D:\ProgramFiles\Java\jdk1.8.0_251\lib\jconsole.jar;D:\ProgramFiles\Java\jdk1.8.0_251\lib\packager.jar;D:\ProgramFiles\Java\jdk1.8.0_251\lib\sa-jdi.jar;D:\ProgramFiles\Java\jdk1.8.0_251\lib\tools.jar;E:\JVMDemo\out\production\chapter17 com.atguigu.java.GCUseTest

-XX:InitialHeapSize=250603712 -XX:MaxHeapSize=4009659392 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParNewGC

在命令行下测试(JDK 8下使用组合UseParNewGC + UseSerialOldGC)

E:\JVMDemo>jps

2384

5300 Jps

12120 RemoteMavenServer36

1800 GCUseTest

536 Launcher

E:\JVMDemo>jinfo -flag UseSerialOldGC 1800

no such flag 'UseSerialOldGC'

E:\JVMDemo>jinfo -flag UseConcMarkSweepGC 1800

-XX:-UseConcMarkSweepGC

b 使用 -XX:+PrintCommandLineFlags -XX:+UseParNewGC -XX:+UseConcMarkSweepGC 进行测试

在 JDK8的情况下测试结果为

D:\ProgramFiles\Java\jdk1.8.0_251\bin\java.exe -XX:+PrintCommandLineFlags -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -javaagent:D:\ProgramFiles\JetBrains\IDEA\lib\idea_rt.jar=53432:D:\ProgramFiles\JetBrains\IDEA\bin -Dfile.encoding=UTF-8 -classpath D:\ProgramFiles\Java\jdk1.8.0_251\lib\ant-javafx.jar;D:\ProgramFiles\Java\jdk1.8.0_251\lib\dt.jar;D:\ProgramFiles\Java\jdk1.8.0_251\lib\javafx-mx.jar;D:\ProgramFiles\Java\jdk1.8.0_251\lib\jconsole.jar;D:\ProgramFiles\Java\jdk1.8.0_251\lib\packager.jar;D:\ProgramFiles\Java\jdk1.8.0_251\lib\sa-jdi.jar;D:\ProgramFiles\Java\jdk1.8.0_251\lib\tools.jar;E:\JVMDemo\out\production\chapter17 com.atguigu.java.GCUseTest

-XX:InitialHeapSize=250603712 -XX:MaxHeapSize=4009659392 -XX:MaxNewSize=697933824 -XX:MaxTenuringThreshold=6 -XX:OldPLABSize=16 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseConcMarkSweepGC -XX:-UseLargePagesIndividualAllocation -XX:+UseParNewGC

在 JDK9的情况下进行测试

D:\ProgramFiles\Java\jdk-9\bin\java.exe -XX:+PrintCommandLineFlags -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -javaagent:D:\ProgramFiles\JetBrains\IDEA\lib\idea_rt.jar=53633:D:\ProgramFiles\JetBrains\IDEA\bin -Dfile.encoding=UTF-8 -classpath E:\JVMDemo\out\production\chapter17 com.atguigu.java.GCUseTest

-XX:InitialHeapSize=250603712 -XX:MaxHeapSize=4009659392 -XX:MaxNewSize=697933824 -XX:MaxTenuringThreshold=6 -XX:+PrintCommandLineFlags -XX:ReservedCodeCacheSize=251658240 -XX:+SegmentedCodeCache -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseConcMarkSweepGC -XX:-UseLargePagesIndividualAllocation -XX:+UseParNewGC

OpenJDK 64-Bit Server VM warning: Option UseParNewGC was deprecated in version 9.0 and will likely be removed in a future release.

OpenJDK 64-Bit Server VM warning: Option UseConcMarkSweepGC was deprecated in version 9.0 and will likely be removed in a future release.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值