Java 单CPU机器的最佳GC线程数
我将G1垃圾收集器用于一个应用程序,该应用程序应该使用一个CPU内核(这是一个运行在Thread上的Spark作业),但可能是因为JVM看到了所有可用的内核,所以它使用了相当多的并行线程,从18个到23个。这真的重要吗?我应该手动设置并行线程的数量吗?首先,这里有一个非常有趣的观察结果(至少在Java 单CPU机器的最佳GC线程数,java,memory-management,garbage-collection,g1gc,Java,Memory Management,Garbage Collection,G1gc,我将G1垃圾收集器用于一个应用程序,该应用程序应该使用一个CPU内核(这是一个运行在Thread上的Spark作业),但可能是因为JVM看到了所有可用的内核,所以它使用了相当多的并行线程,从18个到23个。这真的重要吗?我应该手动设置并行线程的数量吗?首先,这里有一个非常有趣的观察结果(至少在jdk-15上) 假设此代码: public class Sandbox { public static void main(String[] args) { whi
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 VM.flags
连接到它,注意一件非常有趣的事情:-XX:+UseSerialGC
。由于您指定了单个CPU,因此根据JVM
(这很有意义)使用G1GC
没有意义。所以要做好准备
您可以通过:-XX:ActiveProcessorCount=
查看所需的CPU数量,这是JVM将看到的CPU数量(并且很可能在内部基于此构建启发式)
G1
使用两种类型的线程:ParallelGCThreads
和congcthreads
,它们实现不同的目的
如果我从上面做了同样的练习(启动一个进程并连接到它,但也启用了-XX+UseG1GC
),我看到并行GCThreads
没有改变(默认为10
),也没有改变congcThreads
(默认为3
);这对我来说是个惊喜。或者不是。这取决于您如何看待它-VM试图禁止使用G1GC
当然,10个并行线程竞争1个CPU并不是设置虚拟机的好方法。实际上,G1是偶然使用的,因为它在Spark optimization guide中提到过,真正的问题是年轻一代的大小——不管出于什么原因,默认GC没有增加其大小,即使程序产生300MB/s的垃圾。但是SerialGC没有字符串重复数据消除功能,不是吗?此外,除非它被大量重写,否则它僵化的内存组织可能会导致比现代算法更差的性能。@Holger我试过SerialGC,但性能很差,现在我已经知道了发生了什么,我问了一个新问题