我正在用Eclipse开发Java程序,该程序可以分析大型物理数据集并运行迭代优化过程。在对具有大量迭代的特别大的数据集进行测试时,我看到了我无法解释的现象。
以下是设置线程的方式:
List<String> scenarios;
List<Thread> threads = new ArrayList<Thread>();
final int cores = Runtime.getRuntime().availableProcessors() - 1;
for(final String scenario: scenarios) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
innerLoopParallel(); //each optimization iteration
} catch (Exception e) {
e.printStackTrace();
}
});
if(threads.size() < cores) {
thread.start();
threads.add(thread);
}
}
for (Thread thread: threads) {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
我的机器有8个核心,我正在多线程化到7个核心上。迭代过程最初运行时确实非常快,但是运行约20分钟后,其运行速度却相当慢。我最初的想法是内存限制,但是我一直在关注堆状态(在Eclipse中,Window->首选项->常规->“显示堆状态”),而且似乎并没有达到极限。但是,我的CPU已经用光了(见图),风扇猛烈吹动。在每次迭代时,都应该在控制台上打印一行,但是随着程序速度的降低,它开始成块写入,每次打印20条。
我知道这个问题有些含糊,但我的想法已经用完了。您有什么建议可以指示我正确的方向吗?多线程会引起问题吗? for循环是否有可能通过不关闭某些进程而以某种方式建立CPU?如果您需要任何澄清,请随时提出问题。
答案 0 :(得分:1)
您有什么建议可以指示我正确的方向吗?
使用探查器来找出应用程序在所有时间上所花费的时间。
多线程是否会引起问题?
可能。尤其是如果您创建了太多线程和/或在线程之间进行了太多上下文切换。
for循环是否有可能通过不关闭某些进程而以某种方式建立CPU?
这个问题(对我而言)真的没有意义。
但是,由于循环要在越来越大的数据结构上运行,因此循环花费的时间越来越长是合理的。还有很多其他可能的原因导致算法会随着时间的推移变得非常缓慢/非常占用CPU。
建议:
更新
我可以看到您的线程代码有问题。例如,看起来某些线程永远不会启动。但是 1 也有明显迹象表明这不是真实代码,因此对其进行分析很有用。
但是,我不应该那样做,而应该使用ExecutorService
和叉连接池中有界的线程池。 (不确定哪个是最好的...。因为您的示例代码太抽象了。)进行自己的线程池管理不是一个好主意,而且已经20多年了!
另一方面,没有一种或多种方式的真实证据表明线程是问题所在。请参阅我的早期建议!
1-例如,监视显示有超过2500个本机线程。但是,您显示给我们的代码不应该发生这种情况。