簡體   English   中英

Java 多線程在長時間進程中變慢,最大 CPU 使用率

[英]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 行。

最大 CPU 使用率

我知道這個問題有點含糊,但我的想法不多了。 您有什么建議可以為我指明正確的方向嗎? 多線程會導致問題嗎? for 循環是否有可能通過不關閉某個進程來以某種方式建立 CPU? 如果您需要澄清任何問題,請隨時提出問題。

您有什么建議可以為我指明正確的方向嗎?

使用分析器找出您的應用程序將所有時間都花在了哪里。

多線程會導致問題嗎?

潛在的。 特別是如果您創建了太多線程和/或在線程之間進行了太多上下文切換。

for 循環是否有可能通過不關閉某個進程來以某種方式建立 CPU?

這個問題(對我來說)沒有意義。

但是 for 循環花費的時間越來越長是合理的,因為它們在越來越大的數據結構上運行。 隨着時間的推移,算法可能會變得非常緩慢/非常占用 CPU,還有許多其他可能的原因。

建議:

  • 分析您的代碼/算法以及您使用線程的方式。
  • 考慮進行 Big O 復雜性分析。
  • 考慮您的應用程序是否由於非本地化內存訪問模式而導致過度的內存爭用和緩存抖動。

更新

我可以看到您的線程代碼有問題。 例如,看起來某些線程永遠不會啟動。 但是也有明顯的跡象1表明這不是真正的代碼,因此分析它的實用性值得懷疑。

但不是這樣做,我認為你應該使用一個ExecutorService和一個有界線程池,一個 fork 連接池。 (不確定哪個最好......因為你的示例代碼太抽象了。)做你自己的線程池管理不是一個好主意,而且已經有 20 多年了!

另一方面,沒有真正的證據表明線程是問題所在。 看我之前的建議!


1 - 例如,監控顯示有 >2500 個本機線程。 但是,您向我們展示的代碼不應該發生這種情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM