2009-10-20 102 views
87

我正在一個多線程程序java.lang.OutOfMemoryError:Java堆空間

java.lang.OutOfMemoryError: Java heap space 

在一個線程發生上述錯誤的執行下面的錯誤。

  1. 我的知識,堆空間只被實例變量佔用。如果這是正確的,那麼爲什麼這個錯誤在運行正常之後發生,因爲在創建對象時分配了實例變量的空間。

  2. 有什麼辦法可以增加堆空間嗎?

  3. 我應該對我的程序做些什麼改變才能獲得更少的堆空間?

+4

檢查http://stackoverflow.com/questions/37335/how-to-deal-with-java-lang-outofmemoryerror-java-heap-space-error-64mb-heap-s – JuanZe 2009-10-20 17:07:12

回答

95

如果要增加堆空間,可以在命令行上使用java -Xms<initial heap size> -Xmx<maximum heap size>。默認情況下,這些值基於JRE版本和系統配置。你可以找到more about the VM options on the Java website

但是,我會建議分析您的應用程序以找出您的堆大小被吃掉的原因。 NetBeans的very good profiler包含在其中。我相信它在引擎蓋下使用了jvisualvm。使用探查器,您可以嘗試查找正在創建多個對象的位置,對象何時被垃圾收集等等。

+1

我使用Netbeans,但我不知道如何使用探查器。我想了解更多關於分析器的知識,以便我可以使用它在我的應用程序中查找內存泄漏。 – 2009-10-20 18:00:04

+0

我在NetBeans站點(http://profiler.netbeans.org/)上添加了一個鏈接,該鏈接有關於配置文件的非常好的文檔,從非常基礎到更高級的用途。 – 2009-10-20 18:03:23

+0

默認值隨Java版本而變化,在您的答案中包含[此信息](http://stackoverflow.com/questions/28272923/default-xmxsize-in-java-8)將會很好。 – Dariusz 2016-05-06 08:07:41

6

要增加堆大小,可以在啓動Java時使用-Xmx參數;例如

-Xmx256M 
1

不,我想你是在考慮堆棧空間。堆空間被對象佔用。增加它的方法是-Xmx256m,用命令行上所需的數量替換256。

25

1.-是的,但它幾乎指的是程序使用的整個內存。

2:是的,請參閱Java VM選項

-Xms<size>  set initial Java heap size 
-Xmx<size>  set maximum Java heap size 

java -Xmx2g分配2 GB的RAM作爲最大的爲您的應用

但是你應該看到,如果你沒有一個內存泄漏第一。

3.-這取決於程序。嘗試點內存泄漏。這個問題很難回答。最近,您可以使用JConsole進行配置文件,試圖找出內存的位置

+0

while(true);'給出內存不足錯誤? – 2009-10-20 17:12:33

+5

哪個'while(true);'??? ;) – OscarRyz 2009-10-20 17:28:28

+0

while which(true);) – 2014-12-08 22:52:37

3
  1. 局部變量位於堆棧上。堆空間被對象佔用。可以使用-Xmx選項。

  2. 基本上堆空間已用完,每次您分配一個新對象new並在對象不再被引用後釋放一段時間。因此,請確保您不保留對不再需要的對象的引用。

8

你可能想看看這個網站,瞭解更多關於JVM內存: http://developer.streamezzo.com/content/learn/articles/optimization-heap-memory-usage

我認爲它是有用使用visualgc觀看內存模型的不同部分如何填補確定要改變的是什麼。

這是很難確定哪部分內存被填滿,因此visualgc的,因爲你可能只想改變是有一個問題,而不是隻說了一部分,

Fine! I will give 1G of RAM to the JVM.

儘量更準確地說明你正在做什麼,從長遠來看,你可能會發現程序更好。

要確定內存泄漏的位置,您可以使用單元測試,通過測試測試之前和之後的內存,以及如果變化太大,則可能需要檢查它,但,當您的測試仍在運行時,您需要執行檢查。

5
  1. 在大多數情況下,代碼並未優化。釋放你認爲不需要的物體。避免每次在循環中創建對象。嘗試使用緩存。我不知道你的應用程序在做什麼。但在編程時,正常生活的一個規則也適用

    預防勝於治療。 「不要創建不必要的對象」

5
  1. Upto my knowledge, Heap space is occupied by instance variables only. If this is correct, then why this error occurred after running fine for sometime as space for instance variables are alloted at the time of object creation.

這意味着你在一段時間內連續創造了你的應用程序更多的對象。新的對象將被存儲在堆內存中,這就是堆內存增長的原因。

堆不僅包含實例變量。它將存儲所有非原始數據類型(對象)。這些對象的使用壽命可能會很短(方法塊)或很長(直到在您的應用程序中引用該對象)

  1. Is there any way to increase the heap space?

是的。看看這個oracle article瞭解更多詳情。

有兩個參數用於設定堆大小:

-Xms:,其中設置初始和最小堆大小

-Xmx:,它設置最大堆大小

  1. What changes should I made to my program so that It will grab less heap space?

這取決於您的應用程序。

  1. 設置最大堆內存根據您的應用需求

  2. 不會引起你的應用程序的內存泄漏

  3. 如果你發現你的應用程序的內存泄漏,找出根源與諸如MAT,Visual VM,jconsole等分析工具的幫助一旦找到根本原因,修復泄漏。

從Oracle的重要注意事項article

Cause: The detail message Java heap space indicates object could not be allocated in the Java heap. This error does not necessarily imply a memory leak.

可能的原因:

  1. 配置不當(不分配sufficiant內存)
  2. 應用無意中持有的對象,這引用防止對象被垃圾收集ed
  3. 過度使用終結器的應用程序。如果某個類具有finalize方法,則該類型的對象在垃圾回收時沒有回收空間。 如果終結器線程跟不上終止隊列,那麼Java堆可能會被填滿,並且這種類型的OutOfMemoryError異常將被拋出

在不同的音符,用更好的垃圾收集算法(CMSG1GC

看一看這個question理解G1GC

0

在NetBeans中,進入 '運行'工具欄 - >'設置項目配置' - >'自定義' - >'運行'彈出窗口 - >'虛擬機選項' - >填寫'-Xms2048m -Xmx2048m'。它可以解決堆大小問題。

相關問題