在某些目的中,需要让JVM
认为它在机器上运行N
核心而不是实际核心数(例如4
核心而不是{{1} }})。
16
在一些Linux版本下运行,基于Mandriva / Red Hat Linux核心。
这个问题是边缘情况,因为我期待这个问题的各种解决方案。这不是纯粹的linux管理问题,也不是纯粹程序员的问题。
所以...任何想法?
答案 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命名空间启动新进程。