标签: stack-overflow

什么是StackOverflowError?

什么是什么,是StackOverflowError什么导致它,我应该如何处理它们?

stack-overflow memory-leaks exception-handling out-of-memory

420
推荐指数
10
解决办法
58万
查看次数

Try-finally块阻止StackOverflowError

看看以下两种方法:

public static void foo() {
    try {
        foo();
    } finally {
        foo();
    }
}

public static void bar() {
    bar();
}
Run Code Online (Sandbox Code Playgroud)

运行bar()清楚导致a StackOverflowError,但运行foo()没有(程序似乎只是无限期运行).这是为什么?

java stack-overflow recursion try-finally

329
推荐指数
5
解决办法
1万
查看次数

实际导致Stack Overflow错误的原因是什么?

我到处寻找,找不到可靠的答案.根据文档,Java 在以下情况下抛出java.lang.StackOverflowError错误:

在发生堆栈溢出时抛出,因为应用程序过于严重.

但这提出了两个问题:

  • 是否有其他方法可以发生堆栈溢出,而不仅仅是通过递归?
  • StackOverflowError是否在JVM实际溢出堆栈之前或之后发生?

详细说明第二个问题:

当Java抛出StackOverflowError时,你能安全地假设堆栈没有写入堆中吗?如果你在一个抛出堆栈溢出的函数的try/catch中缩小堆栈或堆的大小,你能继续工作吗?这记录在哪里?

答案我不是在寻找:

  • 由于错误的递归而发生StackOverflow.
  • 当堆遇到堆栈时发生StackOverflow.

java stack-overflow jvm

235
推荐指数
3
解决办法
9万
查看次数

Python优化尾递归吗?

我有以下代码失败,出现以下错误:

RuntimeError:超出最大递归深度

我试图重写它以允许尾递归优化(TCO).我相信如果发生TCO,这段代码应该是成功的.

def trisum(n, csum):
    if n == 0:
        return csum
    else:
        return trisum(n - 1, csum + n)

print(trisum(1000, 0))
Run Code Online (Sandbox Code Playgroud)

我是否应该断定Python不执行任何类型的TCO,或者我只是需要以不同的方式定义它?

python stack-overflow recursion stack tail-recursion

182
推荐指数
5
解决办法
6万
查看次数

为什么#include <string>会阻止堆栈溢出错误?

这是我的示例代码:

#include <iostream>
#include <string>
using namespace std;

class MyClass
{
    string figName;
public:
    MyClass(const string& s)
    {
        figName = s;
    }

    const string& getName() const
    {
        return figName;
    }
};

ostream& operator<<(ostream& ausgabe, const MyClass& f)
{
    ausgabe << f.getName();
    return ausgabe;
}

int main()
{
    MyClass f1("Hello");
    cout << f1;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果我注释掉,#include <string>我没有得到任何编译器错误,我想因为它包含在内#include <iostream>.如果我在Microsoft VS中"右键单击 - >转到定义",它们都指向xstring文件中的同一行:

typedef basic_string<char, char_traits<char>, allocator<char> >
    string;
Run Code Online (Sandbox Code Playgroud)

但是当我运行我的程序时,我收到一个异常错误:

OperatorString.exe中的0x77846B6E(ntdll.dll):0xC00000FD:堆栈溢出(参数:0x00000001,0x01202FC4)

知道为什么我在评论时出现运行时错误#include <string> …

c++ stack-overflow string explicit

121
推荐指数
2
解决办法
7251
查看次数

如何增加Java堆栈大小?

我问这个问题是为了了解如何在JVM中增加运行时调用堆栈的大小.我已经得到了答案,我还得到了许多有用的答案和评论,这些答案和评论与Java如何处理需要大型运行时堆栈的情况有关.我已经用答案摘要扩展了我的问题.

最初我想增加JVM堆栈大小,所以程序就像没有运行的程序一样StackOverflowError.

public class TT {
  public static long fact(int n) {
    return n < 2 ? 1 : n * fact(n - 1);
  }
  public static void main(String[] args) {
    System.out.println(fact(1 << 15));
  }
}
Run Code Online (Sandbox Code Playgroud)

相应的配置设置是java -Xss...具有足够大值的命令行标志.对于TT上面的程序,它与OpenJDK的JVM一样:

$ javac TT.java
$ java -Xss4m TT
Run Code Online (Sandbox Code Playgroud)

其中一个答案还指出,这些-X...标志是依赖于实现的.我在用

java version "1.6.0_18"
OpenJDK Runtime Environment (IcedTea6 1.8.1) (6b18-1.8.1-0ubuntu1~8.04.3)
OpenJDK 64-Bit Server VM (build 16.0-b13, mixed mode)
Run Code Online (Sandbox Code Playgroud)

也可以仅为一个线程指定一个大堆栈(参见其中一个答案如何).建议使用此方法java -Xss...以避免为不需要它的线程浪费内存.

我很好奇上面的程序需要多大的堆栈,所以我运行它n增加了:

  • -Xss4m就足够了 fact(1 …

java stack-overflow stack

114
推荐指数
4
解决办法
17万
查看次数

为什么这个方法打印4?

我想知道当你试图捕获StackOverflowError时会发生什么,并提出以下方法:

class RandomNumberGenerator {

    static int cnt = 0;

    public static void main(String[] args) {
        try {
            main(args);
        } catch (StackOverflowError ignore) {
            System.out.println(cnt++);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我的问题:

为什么这个方法打印'4'?

我想也许是因为System.out.println()在调用堆栈上需要3个段,但我不知道3号来自哪里.当你查看源代码(和字节码)时System.out.println(),它通常会导致比3更多的方法调用(因此调用堆栈上的3个段是不够的).如果是因为优化热点VM应用(方法内联),我想知道其他VM上的结果是否会有所不同.

编辑:

由于输出似乎是高度JVM特定的,我使用
Java(TM)SE运行时环境(构建1.6.0_41-b02)
Java HotSpot(TM)64位服务器VM(构建20.14-b01,混合模式)得到结果4


解释为什么我认为这个问题与理解Java堆栈不同:

我的问题不是为什么有一个cnt> 0(显然是因为System.out.println()需要堆栈大小并StackOverflowError在某些东西被打印之前抛出另一个),但为什么它具有特定值4,分别为0,3,8,55或其他的其他东西系统.

java stack-overflow jvm

111
推荐指数
5
解决办法
4310
查看次数

C#捕获堆栈溢出异常

我得到一个递归调用一个抛出堆栈溢出异常的方法.第一个调用被try catch块包围,但没有捕获异常.

堆栈溢出异常是否以特殊方式运行?我可以正确捕获/处理异常吗?

注意:如果相关:

  • 主线程中没有抛出异常

  • 代码抛出异常的对象由Assembly.LoadFrom(...)手动加载.CreateInstance(...)

c# stack-overflow try-catch

110
推荐指数
8
解决办法
9万
查看次数

Chrome/jQuery Uncaught RangeError:超出了最大调用堆栈大小

我在chrome上收到错误"未捕获RangeError:超出最大调用堆栈大小".这是我的jQuery函数

$('td').click(function () {
        if ($(this).context.id != null && $(this).context.id != '') {
            foo($('#docId').val(), $(this).attr('id'));
        }
        return false;
    });
Run Code Online (Sandbox Code Playgroud)

请注意,页面中有数万个单元格.但是,我通常将堆栈溢出与递归相关联,在这种情况下,据我所知,没有.

创建这样的lambda会自动在堆栈上生成一堆东西吗?有什么办法吗?

目前我唯一的解决方法是在呈现HTML时在每个单元格上显式生成onclick事件,这使得HTML更大.

javascript stack-overflow jquery webkit google-chrome

105
推荐指数
3
解决办法
28万
查看次数

为什么可以从StackOverflowError中恢复?

我很惊讶即使StackOverflowError在Java发生之后仍然可以继续执行.

我知道这StackOverflowError是类Error的子类.类Error被称为"Throwable的一个子类,表示一个合理的应用程序不应该试图捕获的严重问题".

这听起来更像是一个推荐而不是一个规则,主张捕获像StackOverflowError这样的错误实际上是允许的,这取决于程序员不这样做的合理性.看,我测试了这段代码,它正常终止.

public class Test
{
    public static void main(String[] args)
    {
        try {
            foo();
        } catch (StackOverflowError e) {
            bar();
        }
        System.out.println("normal termination");
    }

    private static void foo() {
        System.out.println("foo");
        foo();
    }

    private static void bar() {
        System.out.println("bar");
    }
}
Run Code Online (Sandbox Code Playgroud)

怎么会这样?我想当抛出StackOverflowError时,堆栈应该是如此完整,以至于没有空间调用另一个函数.错误处理块是在不同的堆栈中运行,还是在这里发生了什么?

java stack-overflow

99
推荐指数
5
解决办法
5292
查看次数