2014-10-31 52 views
2

我有一個大規模創建線程的應用程序。因此,我得到一個OutOfMemoryError。我的想法是等到有足夠的可用空間來創建下一個線程。但是,因此我需要知道創建線程需要多少內存,以及這個內存量是否可用。有沒有辦法獲得線程需要的內存量?我如何確定這個內存量是否可用?Java需要內存用於新線程

我已經嘗試過:

for (int i = 0; i < links.size(); i++) { 
    while(Runtime.getRuntime().maxMemory() - Runtime.getRuntime().totalMemory() + 
     Runtime.getRuntime().freeMemory() < MEMORY_THRESHOLD) { 
     synchronized (lock) { 
      lock.wait(10); 
     } 
    } 
    Thread t = new Thread(new Task(links.get(i))); 
    t.setDaemon(true); 
    t.start(); 
} 

但是,即使當我使用100MB的門檻,我得到一個的OutOfMemoryError

+0

我不是專家創造這麼多線程,但我覺得你比較蘋果與橘子行:'.maxMemory() - unMemory.getRuntime()。totalMemory()',maxMemory和totalMemory聲音與我不同 – Coffee 2014-10-31 15:23:55

+2

爲什麼你會創建大量的線程? – RobAu 2014-10-31 15:26:54

+1

@Coffee這應該是JVM可以分配的內存,當我使用freeMemory()時,它會在第一個線程創建之前阻塞。 – kaetzacoatl 2014-10-31 15:27:58

回答

6

沒有,你去刪除此代碼,並使用ThreadPool代替。你想做的事情很難,你應該使用更高的抽象,你必須做多線程,或者你根本不這樣做。

Check out執行人,目前他們是更高的抽象。 如果您的任務是計算綁定的,那麼Java 7中的ForkJoin是您的朋友,只要您知道如何遞歸地將問題劃分爲子問題,則無需擔心池的大小。

+0

您的解決方案有效,但我仍然不知道我可以創建多少個線程。 Executors.newFixedThreadPool()問我最大的線程數量,但那正是我不知道的。 – kaetzacoatl 2014-10-31 15:40:53

+3

@kaetzacoatl之間的cpu核心數量和兩倍之間,更多和性能降低不必要的。如果你有大量的線程等待整天使用異步框架。 – Voo 2014-10-31 15:45:22

1

沒有足夠的關於該問題的信息來建議最佳解決方案。

通常,您可能需要比你的實際CPU核心創建多個多個線程,當你有昂貴的I/O操作。從links變量來看,這可能是其中的一種情況,但正如其他人所暗示的那樣,創建太多線程通常意味着一個糟糕的設計。它甚至可能會讓系統耗盡可用資源。

即使打算在網絡上時,你的帶寬是固定的,所以除非你有一個互聯網骨幹網直接訪問它是極不可能的,你會得到任何性能優勢,因爲大多數網站應具有高速響應。

話說回來,即使你放慢線程創建你無法控制一個線程需要多少內存消耗和在什麼時候。即所有線程可能會同時開始下載數據,即使您沒有創建任何新線程,仍會耗盡內存。

總之,跟着別人的網友建議:

  • 使用ExecutorService
  • 瞭解更多一點關於線程(Java併發實踐中,是一個非常好的源)
  • 想想你爲什麼創造這麼多線程?你爲什麼期望無論你做什麼都會更快?

PS。它還將幫助,如果你提供你爲什麼需要在你的問題