2009-11-04 242 views
0

我的內存不足錯誤。我有一個大範圍的輸入(2^40),這是太大,不能立即舉行。每個輸入是一個String[]。相反,我想我會在每個輸入上運行測試程序,將結果寫入文件,然後丟棄輸入。最長輸入的length是42,所以這不是導致溢出的錯誤。我不認爲我理解垃圾收集。Java:垃圾回收

PowerSet就像是一個懶惰的列表 - 直到調用.next()纔算出結果。每個結果返回baseSet的一個子集。 baseSet是長度爲40的字符串[]。 runTests對輸入進行了一些分析並將其寫入文件。

PowerSet argSetSet = powerset(baseSet); 
while (argSetSet.hasNext()) { 
    runTests(argSetSet.next()); //saves output to file 
} 

這會導致內存不足錯誤。但是我沒有將argSetSet.next()的結果保存在任何地方,那麼爲什麼會發生這種情況呢?我不需要存儲來自next()runTests()的任何數據。我如何確保它們都被垃圾收集?

如果我註釋掉runTests(),它運行良好。

+4

什麼是確切的錯誤信息?它是一個'OutOfMemoryError',它表明太多的對象?或者是一個'StackOverflowError',它提示了一個遞歸錯誤? – McDowell 2009-11-04 17:30:19

+0

錯誤是'OutOfMemory' – 2009-11-04 20:46:12

回答

4

沒有足夠的代碼來理解發生了什麼,主要是PowerSet,但PowerSet必須計算String數組才能返回下一個方法。它可能是它堅持那個對象。

內存問題在runTests方法或PowerSet類中。它不在您發佈的代碼中。

0

什麼是baseSet?我猜這就是用了大量的內存。當PowerSet內部使用baseSet時,這可能會加劇。

0

,你是不是存儲.next()結果,這一事實在任何地方是不相關的,決定性的標準是什麼.next()實際上做的事情。

您是否將堆大小設置爲非默認大小?您使用什麼設置來啓動JVM? JVM的缺省堆大小僅爲64M,因此one trillion條目肯定不適合該空間。

2

附加一個像jvisualvm這樣的剖析器,並調查你的記憶在哪裏。你可能會感到驚訝:)

0

[Clippy-like icon]看來你正在計算一個非常大的集合的powerset。你想增加堆大小嗎?

我擔心的是你說這是一個懶惰的列表,這意味着整個powerset實際上並不在內存中,但是當你調用.next()函數時,只有一部分內存在內存中。 。但是,根據.next()實際返回的內容(數組的大小),默認堆大小很可能是不夠的。

您可以通過指定 - Xmx1024m(將堆的最大值大小設置爲1GB)來增加堆的大小。顯然你可以調整這個大小,但是這將允許你測試它是否會縮放。這不是一個最終的解決方案,但它至少應該給你一些跑道。

+0

'next()'返回的數組的最大大小是40. – 2009-11-04 21:22:12

+0

好吧,那絕對是關閉的。我建議下載一個類似yourkit(yourkit.com)的探查器並嘗試他們的Java Profiler。你可以看到內存在哪裏。根據您的評論判斷,您將保留runTests中內存中字符串的數組或值。不確定是否要將該方法公開給我們,但要查找將它放置在地圖/列表/集合中的位置,並且不要清除地圖或使用靜態集合。 – Malaxeur 2009-11-05 05:29:51