Я использую сборщик мусора G1 для приложения, которое должно использовать одно ядро ЦП (это задание Spark, работающее на Yarn), но, вероятно, поскольку JVM видит все доступные ядра, оно использует довольно большое количество параллельных потоков, от 18 до 23. , Это действительно имеет значение? Должен ли я установить количество параллельных потоков вручную?
Оптимальное количество потоков GC для машины с одним процессором
Ответы (1)
Вот довольно интересное наблюдение, во-первых (по крайней мере, на 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
. Поскольку вы указали один ЦП, нет смысла использовать G1GC
в соответствии с JVM
(что имеет смысл). Так что будьте готовы.
Вы можете делать то, что хотите, через: -XX:ActiveProcessorCount=
, и именно столько процессоров увидит ваша JVM (и, скорее всего, на основе этого будет построена внутренняя эвристика).
Существует два типа потоков, которые использует G1
: ParallelGCThreads
и ConcGCThreads
, которые выполняют разные задачи.
Если я выполняю то же упражнение, что и выше (запускаю процесс и подключаюсь к нему, но также включаю -XX+UseG1GC
), я вижу, что ParallelGCThreads
не изменяется (по умолчанию 10
), а также ConcGCThreads
(что по умолчанию до 3
); что для меня неожиданность. Или нет. Это зависит от того, как вы на это посмотрите - виртуальная машина пыталась запретить использование G1GC
для начала.
Конечно, 10 параллельных потоков, конкурирующих за 1 ЦП, — не лучший способ настроить вашу виртуальную машину.