繁体   English   中英

在java中尝试/捕获堆栈溢出?

[英]try/catch on stack overflows in java?

你能在java中尝试/捕捉堆栈溢出异常吗? 无论哪种方式,它似乎都在投掷自己。 当我的程序溢出时,我想“惩罚”那个值。

似乎工作:

public class Test {

    public static void main(String[] argv){
        try{
            main(null);
        }
        catch(StackOverflowError e){
            System.err.println("ouch!");
        }
    }

}

如果您遇到堆栈溢出,您可能正在尝试无限递归或严重滥用函数调用。 也许您可能会考虑使您的某些过程迭代而不是递归或仔细检查您的递归过程中是否有正确的基本情况。 捕获堆栈溢出异常是个坏主意。 您正在治疗症状而没有解决根本原因。

您必须捕获错误,而不是异常

Java 8 的功能特性让这个问题变得无比重要。 因为当我们开始大量使用递归时,StackOverflowException 是我们必须考虑的。

Java 8 lambdas 类型中没有一种会引发 StackOverflowException。 所以,我们必须创造这样的。 这是绝对必要的,否则我们甚至不会通过 IDE 控制。

例如,整数 -> 整数函数类型可能如下所示:

@FunctionalInterface
public interface SoFunction <U> {
    public U apply(Integer index) throws StackOverflowException;
}

之后我们可以编写一个函数来接受抛出 StackOverflowException 的 lambdas。

public T get(int currentIndex) throws StackOverflowException{

只有现在我们才能创建一个递归 lambda:

fiboSequence.setSequenceFunction(
            (i) ->
            fiboSequence.get(i-2).add(fiboSequence.get(i-1))
);

之后,我们可以调用递归链fiboSequence.get(i)并获得结果,如果整个链不可计算,则返回 StackOverflowException。

在使用递归的情况下,SO 的含义完全不同:你跳得太深了,重复它,分成更浅的步骤。

我同意Michael的看法 - StackOverflowException是一个信号,表明出了问题。 吞咽它不是一个好主意。 最好的做法是解决此错误的根本原因。

有时,由于代码的性质,它只是需要增加(取决于操作系统的)堆栈大小,在 Linux 上通常为每个线程 1m。

如果您很高兴代码针对您的用例进行了优化并且仍然遇到此错误,请使用 -Xss2m 增加 VM 的堆栈大小,例如 - 请参阅Oracle 文档

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM