2010-01-06 126 views
0

我的代碼做這樣的事情:主要java.lang.OutOfMemoryError:Java堆空間

for(SomeObject so : someObjects) 
{ 
    Blah b = so; 
    NewObject n = dao.GetNO(b.23); 
} 

,即它正在創造一個新的變量裏面的每個迭代循環。

這可能是內存不足問題的原因嗎?

通過Netbeans的報告的錯誤:

Caused by: java.lang.OutOfMemoryError: Java heap space 
     at java.lang.StringCoding$StringDecoder.decode(StringCoding.java:133) 
     at java.lang.StringCoding.decode(StringCoding.java:173) 
     at java.lang.String.<init>(String.java:443) 
     at java.lang.String.<init>(String.java:515) 
     at com.gargoylesoftware.htmlunit.WebResponseImpl.getContentAsString(WebResponseImpl.java:215) 
     at com.gargoylesoftware.htmlunit.WebResponseImpl.getContentAsString(WebResponseImpl.java:205) 

Upate 這是一個java控制檯應用程序,以及整個應用程序在for循環運行的基本。

+0

這可能是原因,但不一定是。嘗試釋放您不再需要的每個對象。特別是,如果您持有不再需要的對象,請檢查您的所有集合(地圖,列表...)。 – 2010-01-06 18:36:18

+0

您的堆大小設置爲? – 2010-01-06 18:37:09

+0

你可以發佈一些更實際的代碼發生錯誤嗎?有一點需要注意:'com.gargoylesoftware.htmlunit.WebResponseImpl.getContentAsString()'的返回值可能是一個相當大的字符串。 – MatrixFrog 2010-01-06 18:39:30

回答

5

您是否正在運行Java 5或更高版本,或者其中一箇舊版JVM?您可以嘗試使用-XX:+ HeapDumpOnOutOfMemory武裝您的Java命令行或通過JConsole附加到您的進程並請求堆轉儲來追查OOM的原因。然後,您可以使用Eclipse MAT工具打開轉儲並查看對象圖,以查看誰保存到程序中的對象上。 MAT有一個觀點來看那些支配對象圖的對象 - 所以它變得非常清楚究竟是什麼泄漏。查看堆棧跟蹤並沒有什麼幫助,並且可能會產生誤導,因爲程序某個位置的泄漏可能導致其他位置的分配失敗。

+0

考慮到所描述的問題的範圍,這似乎是過度殺傷性的。 – 2010-01-06 21:50:59

+0

真的嗎?在我看到一個OOM後知道什麼對象佔用了堆對我來說並不是過分的。 – 2010-01-06 22:08:50

1

當您試圖抓住更多適合內存的對象時,內存不足。如果你在一個循環中創建一個對象,只要它超出了範圍,就會得到GarbageCollected。

所以,如果你寫

for (.....){ 
    Object o = new Object(); 
} 

-you're從未持有鄰多個實例,所以它不會是原因(除非你存儲參考他們在其他地方,爲例如將它們放入循環範圍外的映射中)。

您需要在代碼中尋找更多引用的地方。從你的帖子中,不可能告訴更多。

順便說一句,您可能還會考慮使用-Xmx和-Xms選項(輸入「java -X」來獲取更多信息)來增加JVM中使用的內存量,這可能會讓它運行,儘管它不會幫助你找到一個錯誤。由於您在netbeans內運行,因此可能會因內存運行在同一個JVM中而導致內存不足。我不使用netbeans,但是你可以檢查netbeans是否允許你分叉一個新的進程來運行你的程序(這樣你就不會在與netbeans共享內存的時候運行),或者嘗試直接在命令行上運行。

0

最有可能的是你不小心抓住了某個地方的某些物體。通常的罪魁禍首是執行不當的緩存或功能相當的緩存。

另一種可能性是你根本沒有足夠的內存用於你正在做的任何事情。 Java啓動(至少Sun默認情況下)具有64 MB的堆。您可以使用-xmx參數更改此設置。

最後,我記得在1.4.X天內,如果有足夠的時間(佔總進程cpu時間的百分比)花費垃圾回收(對於某些特定的垃圾回收器實現),則可能導致OutOfMemoryError。截止值在90%的範圍內。我已經在近十年看到過這種情況,這真是一個神經質的用例。它可能不是這個,但它可能是。我不確定這種行爲在現代Java中是否存在。

我的建議:檢查dao.GetNO(...)的執行情況,看它是否產生任何物體作爲副作用,以及它們的壽命是多少。

相關問題