2009-11-04 108 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