【问题标题】:can i clean stacktrace?我可以清理堆栈跟踪吗?
【发布时间】:2010-09-17 12:32:48
【问题描述】:

我知道我可以使用 Thread.getAllStackTraces() 获取堆栈跟踪(它返回 Map,但 clear 不起作用)。当我运行递归方法时,由于堆栈跟踪太大而出现异常,有什么办法可以清除它?

【问题讨论】:

    标签: java recursion


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      如果您由于递归失控而遇到堆栈溢出,那么您就不走运了。堆栈的内容需要从函数调用返回,没有办法明智地“清理它”。问题不在于 getAllStackTraces() 返回的 Map,而在于堆栈的实际内容。

      您需要重新构建代码,使其不会递归到如此深的层次。

      或者,您可以调查是否可以增加堆栈的大小,但要求非标准堆栈大小通常表示实现存在问题。

      【讨论】:

      • 如果任务是在 JSON 中构建非常深的树 - 没有什么可以称为“有问题的实现”。它是任务,并且不断增长的堆栈大小会影响所有线程,这对于繁重的多线程应用程序来说是非常糟糕的。我仍然找不到任何解决方案。
      【解决方案3】:

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

      如果不是这样,您可以尝试为您的程序分配更多的堆栈空间。在 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
        }
      }
      

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

      【讨论】:

      • 这是有用的信息,但不适用于这个问题。
      猜你喜欢
      • 2016-03-07
      • 1970-01-01
      • 1970-01-01
      • 2019-11-05
      • 2014-03-30
      • 1970-01-01
      • 2020-05-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多