我的代码在具有 128 GB RAM 和 64 个内核的 Windows 2008 Server(64 位)上的 32 位 JVM(JRE v1.6)上运行。但是,我可以指定的最大堆空间是 1.5 GB。我的代码如下所示。
int numThreads = Runtime.getRuntime.availableProcessors();
List<Callable<Long>> tasks = new ArrayList<Callable<Long>>();
File dir = new File("/path/to/data");
File[] dataFiles = dir.listFiles();
for(File dataFile : dataFiles) {
MyTask task = new MyTask(dataFile);
tasks.add(task);
}
ExecutorService executor = Executors.newFixedThreadPoll(numThreads);
List<Future<Long>> results = executor.invokeAll(tasks);
long total = 0L;
for(Future<Long> result : results) {
total += result.get();
}
System.out.println("total = " + total);
executor.shutdown();
此代码引发 OutOfMemoryError。我所做的是将线程数更改为更小。
int numThreads = Runtime.getRuntime.availableProcessors();
if(numThreads < 1 || numThreads > 4) {
numThreads = 4;
}
这个修改后的代码还没有抛出 OutOfMemoryError,但是,这让我很失望,因为有很多资源(RAM 和 CPU 资源)没有被使用。如何在我的环境中最大限度地利用资源?
最重要的是,我想要一些关于 1.5 GB 最大堆空间限制的解决方法的反馈。请注意, Callable<Long> 任务是令人尴尬的并行。
我考虑过创建一个 DOS bat 文件来遍历我的输入文件,然后简单地调用
java -cp %CP% -Xms1024m -Xmx1536m net.analysis.MyProg %1
但这似乎有点古怪/笨拙(现在我必须在 DOS bat 中有逻辑来确定要创建多少个进程,并在生成新进程之前等待这些进程完成)。
任何帮助表示赞赏。