问题描述
我正在为应该使用单个cpu内核的应用程序使用G1垃圾收集器(这是在Yarn上运行的Spark作业),但是可能是因为JVM看到了所有可用的内核,因此它使用了大量的并行线程, 18至23真的重要吗?我应该手动设置并行线程数吗?
解决方法
首先,这是一个非常有趣的观察结果(至少在jdk-15
上如此)。
假设此代码:
public class Sandbox {
public static void main(String[] args) {
while (true) {
LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(10_000));
}
}
}
然后我用java -XX:ActiveProcessorCount=1 Sandbox.java
运行它。通过jcmd <PID> VM.flags
连接到它,并注意到一个相当有趣的东西:-XX:+UseSerialGC
。由于已指定单个 CPU,因此根据G1GC
使用JVM
是没有意义的(这很有意义)。所以要做好准备。
您可以通过-XX:ActiveProcessorCount=
来获得所需的信息,这就是您的JVM将看到多少个CPU(并且很有可能在此基础上在内部构建启发式算法)。
G1
使用两种类型的线程:ParallelGCThreads
和ConcGCThreads
,实现不同的目的。
如果我从上面做同样的练习(开始一个过程并连接到它,但是也启用了-XX+UseG1GC
),我发现ParallelGCThreads
并没有改变(默认为10
),也不为ConcGCThreads
(默认为3
);这对我来说是一个惊喜。或不。这取决于您如何看待-VM试图从一开始就禁止使用G1GC
。
当然,竞争10个并行CPU的10个并行线程不是设置VM的好方法。