2

我正在为学生编写一个教育程序,他们可以在其中看到解决旅行推销员问题(时间消耗、状态的视觉表示等)时不同算法的工作原理。问题是我不仅要展示好的算法,还要展示不好的算法。例如,我为 TSP(可怕的选择)实现了广度优先搜索算法。

程序本身是用 Java 编写的。我有一个用于问题解决算法的单独线程,所有算法都实现了一个特定的接口,允许我在每次迭代后进行干预。

所有在具有 N 个节点(n = 城市数)的树结构上运行的盲搜索算法,每个节点是 N 个元素的数组,该实现在生成大约 50k 个节点后会产生 StackOverFlow 异常。我不想限制用户界面,以便可以使用有限数量的城市 - 模拟退火适用于数千个城市。

这里有一个问题:是否有一些可靠的函数可以在某些指定的逻辑语句中使用,以便我可以识别系统即将崩溃的点?有点风格: if (System.memoryLeft() <= 100 / bytes / ) { // 停止工作并采取行动

提前致谢。

4

2 回答 2

2

检测它是否会抛出错误的最简单方法是等到它抛出错误并捕获它。

try {
   action();
} catch(StackOverflowError ste) {
   // you can't call anything here safely, but you can return or unwind the stack.
}

注意:最大堆栈大小因机器而异,并且基于命令行设置。它不是基于多次调用。

如果您真的担心这个问题,我建议您更改代码以使其不使用递归,并且您可以完全避免此问题。


问题是显示/记录的最大堆栈深度为 1024。如果您有更长的堆栈,您将看不到最初导致它的原因。您可以做的是减少最大堆栈大小-Xss128k(如果您的 JVM 允许,则减少),以便您的堆栈跟踪始终足够短以便被捕获。

public static void main(String... ignored) {
    callMe(1);
}

private static void callMe(int i) {
    callMe(i);
}

当以较小的堆栈大小调用时

at Main.callMe(Main.java:42)
at Main.callMe(Main.java:42)
at Main.callMe(Main.java:42)

many deleted

at Main.callMe(Main.java:42)
at Main.callMe(Main.java:42)
at Main.callMe(Main.java:42)
at Main.main(Main.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
于 2013-04-25T08:09:02.023 回答
1

链接到我的答案。在 C#、C++ 和 Java 中导致堆栈溢出的最简单方法

这个解释是 Java、C、C++ 语言的 StackOverflowException 背后的基本原因。

由于递归方法调用,Stackoverflow 异常通常在任何语言中引起。

假设您有一个方法正在调用自身或无限递归循环的任何其他方法,那么它将导致 Stacoverflow 异常。这背后的原因是方法调用堆栈被归档,它将无法容纳其他方法调用。

方法调用堆栈如下图所示。

在此处输入图像描述

解释——假设 Main 方法有 5 个语句,而第三个方法调用了 methodA,那么 main 方法的执行在 statement3 处暂停,并且 MethosA 将被加载到调用堆栈中。然后方法 A 调用了方法 B。所以 methodB 也被加载到堆栈中。

因此,通过这种方式,无限递归调用使调用堆栈被填满。所以它无法承受更多的方法。所以它会抛出 StackOverflowException。

以及如何遇到它请参阅此链接

计算方法调用堆栈大小以检查 StackOverflowException

我也在寻找我的这个查询的解决方案。

于 2013-04-25T08:04:48.893 回答