我能清理堆栈跟踪吗?

时间:2008-10-16 12:19:44

标签: java recursion

我知道我可以通过使用Thread.getAllStackTraces()获得stacktrace(它返回Map,但是clear不起作用)。当我运行递归方法时,由于堆栈跟踪太大,我可以得到异常,有没有办法清除它?

3 个答案:

答案 0 :(得分:4)

不是导致问题的堆栈跟踪,而是堆栈本身。每次调用方法时,信息都会放在堆栈上,允许您返回调用方法。如果你足够递归,最终你填满堆栈上的所有空间(由最大大小限制),程序就会停止。堆栈跟踪只显示您的呼叫历史记录。您可能正在进行无限递归,并且需要在程序失败之前找到一种方法来停止它。您的算法中存在错误,或者您需要在可用内存范围内找到解决方法。

答案 1 :(得分:1)

如果由于递归失控而导致堆栈溢出,那么你运气不好。从函数调用返回需要堆栈的内容,没有办法明智地“清理它”。问题不是getAllStackTraces()返回的Map,而是堆栈的实际内容。

您需要重新构建代码,以便它不会递归到如此深层次。

或者,您可以调查是否可以增加堆栈的大小,但是需要非标准堆栈大小通常是实现有问题的迹象。

答案 2 :(得分:0)

首先检查你的程序是否在其代码中没有错误导致无限递归导致堆栈溢出。

如果不是这种情况,您可以尝试为程序分配更多堆栈空间。在Linux下,您可以使用ulimit bash命令执行此操作,如:

ulimit -s 8000

甚至

ulimit -s unlimited

如果你真的需要展开堆栈,你可以在C中使用setjmp / longjump或使用异常或延续,如:

struct ClearStack {} ;

void myLongComputationWhichCausesStackOverflow() {
  // do something
  if (needsToClearTheStack)
    throw ClearStack() ;
  // do something else
}

int main(int ac, char *av[]) {
  try {
    mylongcomputation() ;
    // continuation of program
    // no stack clearing occurred
  }
  catch(const ClearStack & cs) {
    // the stack was cleared and do something appropriately
  }
}

它做你想要的,但它不是一个很好的编程风格。请注意,您需要想出一种方法来了解何时清除堆栈。这可能非常困难,因为您无法知道剩余多少堆栈空间或者调用函数是否会溢出堆栈!