Обмани JVM о количестве доступных ядер (на linux)
В какой-то цели нужно сделать JVM
думать об этом работает на машине с N
ядер на борту вместо реального количества ядер (например, 4
ядра вместо 16
).
JVM
работает под сборкой Linux, основанной на ядре Mandriva/Red Hat Linux.
Этот вопрос является пограничным случаем, потому что я ожидаю различных решений этой проблемы. Это не чисто вопрос администрирования Linux, и это не вопрос чисто программиста.
Итак... есть идеи?
2 ответа
Следующая программа Java печатает количество процессоров, видимых Java VM:
public class AvailableProcessors {
public static void main(String... args) {
System.out.println(Runtime.getRuntime().availableProcessors());
}
}
Если я выполняю эту программу на своем домашнем компьютере, она печатает 4
, которое является фактическим количеством ядер (включая гиперпоточность). Теперь давайте обманом заставим виртуальную машину Java поверить, что есть только два процессора:
$ echo '0-1' > /tmp/online
$ mount --bind /tmp/online /sys/devices/system/cpu/online
Если я снова запускаю вышеуказанную программу, она печатает 2
вместо 4
,
Этот трюк влияет на все процессы в вашей системе. Однако можно ограничить эффект только определенными процессами. Каждый процесс в Linux может иметь свое собственное пространство имен точек монтирования. См., Например, раздел Пространства имен предварительной обработки на странице руководства mount (2). Например, вы можете использовать lxc для запуска новых процессов с собственным пространством имен монтирования.
Чтобы сделать Runtime.getRuntime().availableProcessors()
вернуть все, что вы хотите, вы можете переопределить JVM_ActiveProcessorCount
использовать функцию LD_PRELOAD
трюк. Вот небольшая программа для этого:
#include <stdlib.h>
#include <unistd.h>
int JVM_ActiveProcessorCount(void) {
char* val = getenv("_NUM_CPUS");
return val != NULL ? atoi(val) : sysconf(_SC_NPROCESSORS_ONLN);
}
Сначала создайте общую библиотеку этого:
gcc -O3 -fPIC -shared -Wl,-soname,libnumcpus.so -o libnumcpus.so numcpus.c
Затем запустите Java следующим образом:
$ LD_PRELOAD=/path/to/libnumcpus.so _NUM_CPUS=2 java AvailableProcessors