簡體   English   中英

Java內存分配限制

[英]Java memory allocation limit

我有一個產生大量線程的循環。 這些線程除其他外包含2個(大量)StringBuilder對象。 然后這些線程運行並執行其操作。

但是,我注意到經過一定數量的線程處理后,出現了奇怪的崩潰。 我知道這是因為有了這些StringBuilder,因為當我減少它們的初始容量時,我可以啟動更多的線程。 現在,對於這些StringBuilder,它們是在線程對象的構造函數中創建的,如下所示:

StringBuilder a =新的StringBuilder(30000);
StringBuilder b =新的StringBuilder(30000);

它通常崩潰的點是大約550個線程,這導致略大於62MB。 結合該程序的其余部分,正在使用的內存很可能是64MB,我在網上某處讀到的是JVM內存分配池的默認大小。 我不知道這是不是真的。

現在,我在做錯什么嗎,由於設計原因,我以錯誤的方式分配了內存嗎? 還是這是唯一的方法,我應該告訴JVM增加其內存池嗎? 還是完全其他?

另外,請不要告訴我設置較低的容量,我知道這些StringBuilders會在需要時自動增加容量,但是我想解決這個問題。

如果您在StringBuilder中存儲了大量信息,您是否會在某個時候引用它? 如果不是,則將其寫入另一種介質(DB,文件等)。 該程序具有有限的資源,它不能一次擁有整個系統的所有狀態。 -Xmx將為您提供更多的存儲空間,但不會使您的存儲能力無限。

考慮使用ThreadPoolExecutor ,並將池大小設置為計算機上的CPU數量。 創建比CPU多的線程只會增加開銷。

ExecutorService service = Executors.newFixedThreadPool(cpuCount))

另外,您可以通過將字符串寫入文件而不是使用StringBuilder將其保留在內存中來減少內存使用。

假設每個線程1MB。 這就是創建每個進程的RAM成本,超出了進程分配的內存。

正如Gregory所說,為jvm提供一些選項,例如-Xmx。

還可以考慮使用ThreadPool或Executor來確保僅同時運行給定數量的線程。 這樣一來,就可以在不降低速度的情況下保持有限的內存量(因為您的處理器始終無法同時運行550個線程)。

當您使用執行程序時,不要在構造函數中創建StringBuilders,而要在run方法中創建。

您可以使用FileWriter將文本輸出到文件,然后使用FileReader將其拉回。 這樣,您只需要將文件名存儲在內存中,而不是字符串的全部內容即可。

要減少線程數量,您可以使用ExecutorService,或者僅使用從隊列中讀取的幾個線程。

我的猜測是,只需稍加修改,您就可以使程序降為根本不需要太多內存。

暫無
暫無

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

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