为什么此 Java 代码未使用所有 CPU 内核?
2022-09-03 14:30:41
附加的简单Java代码在使用正确的参数启动时应加载所有可用的cpu内核。例如,你从
java VMTest 8 int 0
它将启动8个线程,这些线程除了循环并将2添加到整数之外什么都不做。在寄存器中运行的东西,甚至不分配新的内存。
我们现在面临的问题是,在运行这个简单的程序(当然有24个线程)时,我们不会加载24核计算机(AMD 2个插槽,每个插槽有12个核心)。类似的事情发生在2个程序上,每个程序有12个线程或更小的机器。
因此,我们怀疑JVM(Linux x64上的Sun JDK 6u20)不能很好地扩展。
有没有人看到类似的东西,或者有能力运行它并报告它是否在他/她的机器上运行良好(请> = 8个内核)?想法?
我也在具有8个内核的Amazon EC2上尝试过,但是虚拟机的运行似乎与真实盒子不同,因此加载行为完全奇怪。
package com.test;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
public class VMTest
{
public class IntTask implements Runnable
{
@Override
public void run()
{
int i = 0;
while (true)
{
i = i + 2;
}
}
}
public class StringTask implements Runnable
{
@Override
public void run()
{
int i = 0;
String s;
while (true)
{
i++;
s = "s" + Integer.valueOf(i);
}
}
}
public class ArrayTask implements Runnable
{
private final int size;
public ArrayTask(int size)
{
this.size = size;
}
@Override
public void run()
{
int i = 0;
String[] s;
while (true)
{
i++;
s = new String[size];
}
}
}
public void doIt(String[] args) throws InterruptedException
{
final String command = args[1].trim();
ExecutorService executor = Executors.newFixedThreadPool(Integer.valueOf(args[0]));
for (int i = 0; i < Integer.valueOf(args[0]); i++)
{
Runnable runnable = null;
if (command.equalsIgnoreCase("int"))
{
runnable = new IntTask();
}
else if (command.equalsIgnoreCase("string"))
{
runnable = new StringTask();
}
Future<?> submit = executor.submit(runnable);
}
executor.awaitTermination(1, TimeUnit.HOURS);
}
public static void main(String[] args) throws InterruptedException
{
if (args.length < 3)
{
System.err.println("Usage: VMTest threadCount taskDef size");
System.err.println("threadCount: Number 1..n");
System.err.println("taskDef: int string array");
System.err.println("size: size of memory allocation for array, ");
System.exit(-1);
}
new VMTest().doIt(args);
}
}