4

所以我很喜欢泡菜。当我第一次创建我的 DFS 算法时,我使用了递归。这导致出现 StackOverflow 错误。好吧...没什么大不了的,我只是将其转换为迭代。因此,我将代码转换为迭代,并使用 Stack 来复制方法调用。但是,现在我遇到了 OutOfMemoryError。

我实际上刚刚发现了我的问题,存在循环依赖。(愚蠢的我)但是,我很好奇如果没有循环依赖,其他人会如何处理这个问题。我还应该提到这是在 Java 中。

我的问题几乎是当您知道自己没有无限循环但由于 DFS 搜索中的堆栈而遇到 OutOfMemoryError 时该怎么办。

4

3 回答 3

3

堆栈溢出和内存不足错误的常见原因是程序使用了需要 O(n) 存储(或更多)的算法,最好的做法是找到使用更少存储的算法或技巧,例如 O (1) 或 O(log n)。最常见的例子是以恒定大小的块处理大文件,即使用 O(1) 存储,而不是首先将其完全读入内存,即 O(n)。

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

只有当您确定算法尽可能地保持内存保守并且没有内存错误时,才有意义使用 JVM 内存参数(-Xss设置堆栈大小,-Xms-Xmx设置初始和最大堆大小)。

于 2013-07-18T22:15:15.883 回答
1

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

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

当然,从技术上讲,这两个错误都意味着您没有记忆,但它们中的每一个都以不同的方式发生。一种是通过对方法的无休止的递归调用,另一种是通过溢出内存。

编辑 关于您编辑的问题,除非您的系统中没有足够的内存,否则我认为不会在没有无限循环或递归的情况下发生 stackOverflow。也许增加更多的内存?

于 2013-07-18T21:57:30.550 回答
1

在几乎所有情况下,如果您遇到与内存相关的异常,首先要做的就是仔细考虑您正在做什么(可能由内存分析器协助)。您很有可能持有不再需要的数据。

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

-Xss64m

将堆栈大小设置为 64 兆

-Xmx1024m

将堆大小设置为 1 gig。

于 2013-07-18T22:17:58.777 回答