Обмани 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
Другие вопросы по тегам