欺骗JVM关于可用内核的数量(在linux上)

And*_*niy 13 linux jvm cpu-cores

在某些目的中,需要JVM考虑它在具有N核心的机器上运行而不是真实数量的核心(例如4核心而不是核心16).

JVM 在一些基于Mandriva/Red Hat Linux核心的Linux版本下运行.

这个问题是边缘情况,因为我期待这个问题的各种解决方案.这不是纯粹的linux管理问题,也不是纯粹程序员的问题.

所以...任何想法?

apa*_*gin 11

为了使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);
}
Run Code Online (Sandbox Code Playgroud)

首先,创建一个共享库:

gcc -O3 -fPIC -shared -Wl,-soname,libnumcpus.so -o libnumcpus.so numcpus.c
Run Code Online (Sandbox Code Playgroud)

然后按如下方式运行Java:

$ LD_PRELOAD=/path/to/libnumcpus.so _NUM_CPUS=2 java AvailableProcessors
Run Code Online (Sandbox Code Playgroud)


nos*_*sid 6

以下Java程序打印Java VM所看到的处理器数量:

public class AvailableProcessors {
    public static void main(String... args) {
        System.out.println(Runtime.getRuntime().availableProcessors());
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我在家用计算机上执行此程序,则会打印4,这是实际的核心数(包括超线程).现在让我们让Java VM相信只有两个处理器:

$ echo '0-1' > /tmp/online
$ mount --bind /tmp/online /sys/devices/system/cpu/online
Run Code Online (Sandbox Code Playgroud)

如果我再次运行上述程序,则打印2而不是4.

此技巧会影响系统上的所有进程.但是,可以仅将效果限制为某些过程.Linux上的每个进程都可以拥有自己的挂载点命名空间.请参阅mount(2)手册页中的预处理命名空间部分.例如,您可以使用lxc以自己的mount命名空间启动新进程.