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

时间:2014-03-30 08:25:46

标签: linux jvm cpu-cores

在某些目的中,需要让JVM认为它在机器上运行N核心而不是实际核心数(例如4核心而不是{{1} }})。

16在一些Linux版本下运行,基于Mandriva / Red Hat Linux核心。

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

所以...任何想法?

2 个答案:

答案 0 :(得分: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);
}

首先,创建一个共享库:

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

答案 1 :(得分:6)

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

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

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

$ echo '0-1' > /tmp/online
$ mount --bind /tmp/online /sys/devices/system/cpu/online

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

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