带有DFS的OutOfMemoryError

时间:2013-07-18 21:51:10

标签: java optimization refactoring

所以我非常喜欢泡菜。当我第一次创建我的DFS算法时,我使用了递归。这导致StackOverflow错误。嗯......没什么大不了的,我只是把它转换成迭代。所以我将代码转换为迭代,并使用Stack来复制方法调用。但是,现在我得到了OutOfMemoryError。

我实际上只是发现了我的问题,存在循环依赖。 (愚蠢的我)然而,我很好奇如果没有循环依赖,其他人会如何接近这个。我还应该提到这是用Java。

当你知道你没有无限循环时,我的问题就是做什么,但是由于DFS搜索中的堆栈而遇到OutOfMemoryError。

3 个答案:

答案 0 :(得分:3)

堆栈溢出和内存不足错误的一个常见原因是程序使用需要O(n)存储(或更多)的算法,最佳操作方法是找到一种算法或技巧来减少存储空间,如O(1)或O(log n)。最常见的例子是处理常量大小的块中的大文件,即使用O(1)存储,而不是首先将其完全读入内存,即O(n)。

这些错误的另一个常见原因是简单的错误:当算法需要重用现有的垃圾时,累积不再需要的垃圾或创建新对象。同样在这种情况下,适当的解决方案是定位错误并修复它。

只有当你确定算法是内存保守的时候你才能合理地做出来并且没有内存错误就可以使用JVM内存参数(-Xss来设置堆栈大小-Xms来设置堆栈大小{ {1}}和-Xmx设置初始和最大堆大小)。

答案 1 :(得分:1)

stackOverflow正是它所说的,因为你有一个递归算法,这意味着你的内存堆栈(用于函数调用)已经溢出。看一下调用堆栈文档,了解堆栈指针,框架和返回指针的工作原理:Call Stack

当您创建迭代算法时,内存不足,因为您存储的变量不在调用堆栈中,而是存储在函数本身的内存中(在同一堆栈帧中)。

当然,从技术上讲,这两个错误都意味着你没有留下任何记忆,但每个错误都以不同的方式发生。一种是对方法进行非结束递归调用,另一种是通过溢出内存来进行递归调用。

修改 关于你编辑过的问题,除非系统中没有足够的内存,否则我认为stackOverflow不会发生无限循环或递归。也许添加更多内存?

答案 2 :(得分:1)

在几乎所有情况下,如果你遇到与内存相关的异常,首先要做的就是长时间地思考你正在做什么(可能是由内存分析器辅助)。您很有可能继续使用不再需要的数据。

话虽这么说,如果您确定您的程序行为有效且问题仅仅是由于数据集的大小和/或复杂性,您可以增加应用程序使用的堆栈或堆:

-Xss64m

将堆栈大小设置为64 meg

-Xmx1024m

将堆大小设置为1 gig。