[英]Java multi-threading slows down over long process, maximum CPU usage
我正在用 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 中,窗口 -> 首選項 -> 常規 ->“顯示堆狀態”),而且它似乎沒有最大化。 但是,我的 CPU 已經用盡(見圖),風扇用力吹。 在每次迭代時,它應該向控制台打印一行,但隨着程序變慢,它開始分塊寫入,一次打印 20 行。
我知道這個問題有點含糊,但我的想法不多了。 您有什么建議可以為我指明正確的方向嗎? 多線程會導致問題嗎? for 循環是否有可能通過不關閉某個進程來以某種方式建立 CPU? 如果您需要澄清任何問題,請隨時提出問題。
您有什么建議可以為我指明正確的方向嗎?
使用分析器找出您的應用程序將所有時間都花在了哪里。
多線程會導致問題嗎?
潛在的。 特別是如果您創建了太多線程和/或在線程之間進行了太多上下文切換。
for 循環是否有可能通過不關閉某個進程來以某種方式建立 CPU?
這個問題(對我來說)沒有意義。
但是 for 循環花費的時間越來越長是合理的,因為它們在越來越大的數據結構上運行。 隨着時間的推移,算法可能會變得非常緩慢/非常占用 CPU,還有許多其他可能的原因。
建議:
更新
我可以看到您的線程代碼有問題。 例如,看起來某些線程永遠不會啟動。 但是也有明顯的跡象1表明這不是真正的代碼,因此分析它的實用性值得懷疑。
但不是這樣做,我認為你應該使用一個ExecutorService
和一個有界線程池,一個 fork 連接池。 (不確定哪個最好......因為你的示例代碼太抽象了。)做你自己的線程池管理不是一個好主意,而且已經有 20 多年了!
另一方面,沒有真正的證據表明線程是問題所在。 看我之前的建議!
1 - 例如,監控顯示有 >2500 個本機線程。 但是,您向我們展示的代碼不應該發生這種情況。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.