为了估计最大调用深度,递归方法可以用给定量的存储器实现,在堆栈溢出错误可能发生之前计算所用存储器的(近似)公式是什么?
许多人回答"它依赖",这是合理的,所以让我们通过使用一个微不足道但具体的例子来删除一些变量:
public static int sumOneToN(int n) {
return n < 2 ? 1 : n + sumOneToN(n - 1);
}
Run Code Online (Sandbox Code Playgroud)
很容易证明,在我的Eclipse IDE中运行它会爆炸n不到1000(对我来说非常低).这个调用深度限制是否可以在不执行的情况下估算?
编辑:我不禁认为Eclipse有一个固定的最大调用深度1000,因为我得到了998,但是有一个用于main,一个用于初始调用方法,1000总而言之.这是一个"太圆"的数字恕我直言,是一个巧合.我会进一步调查.我只是Dux开销-Xss vm参数; 它是最大的堆栈大小,所以Eclipse运行器必须-Xss1000设置在某处
运行以下代码示例以:
"线程中的异常"main"java.lang.StackOverflowError"结束
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class TestStream {
public static void main(String[] args) {
Stream<String> reducedStream = IntStream.range(0, 15000)
.mapToObj(Abc::new)
.reduce(
Stream.of("Test")
, (str , abc) -> abc.process(str)
, (a , b) -> {throw new IllegalStateException();}
);
System.out.println(reducedStream.findFirst().get());
}
private static class Abc {
public Abc(int id) {
}
public Stream<String> process(Stream<String> batch) {
return batch.map(this::doNothing);
}
private String doNothing(String test) {
return test;
}
}
}
Run Code Online (Sandbox Code Playgroud)
究竟是什么导致了这个问题?这段代码的哪一部分是递归的,为什么?
今天早上我回答了一个与StackoverflowException相关的问题.该人询问何时发生Stackoverflow异常
查看此链接在C#,C++和Java中导致堆栈溢出的最简单方法
所以我的问题是,有没有任何方法可以在程序中动态计算方法调用堆栈大小,然后在调用方法之前应用检查,该方法检查方法调用堆栈是否有空间来容纳它,以防止StackOverflowException.
因为我是一个java人,我正在寻找java,但也寻找与概念相关的解释,没有任何编程语言的限制.
在Java中,有没有办法知道StackOverflow错误或OutOfMemory异常可能很快发生?
该OutOfMemory例外可能是一个更简单的一个捉,如果一个人能够获得的内存使用统计程序的,如果一个人知道提前多少内存需要之前使用OutOfMemory抛出异常.但这些价值是否可知?
对于StackOverflow错误,有没有办法获得递归深度,以及如何知道递归深度的值会导致错误发生?
通过提前知道这些错误是否会发生,我觉得我可以更优雅地恢复应用程序,而不是看着它崩溃.
据Oracle称,StackOverflowError是:
在发生堆栈溢出时抛出,因为应用程序过于严重.
我知道递归是什么,通常递归函数,如果没有正确终止,会导致StackOverflowError.为了检查StackOverflowError抛出之前发生的递归调用的数量,我写了这段代码:
package ErrorCases;
public class StackOverFlowError {
static int i=0;
void a()
{
//System.out.println("called "+(++i));
try{
++i;
a();
}catch(Error e)
{
System.out.println(e.getClass());
System.out.println(i);
}
}
public static void main(String[] args) {
new StackOverFlowError().a();
}
}
Run Code Online (Sandbox Code Playgroud)
在JVM抛出StackOverflowError之前,i给出递归调用计数的值a().每次运行
的价值i都不同,如:
output 1: class java.lang.StackOverflowError
10466
Output 2: class java.lang.StackOverflowError
10470
Run Code Online (Sandbox Code Playgroud)
我的疑问是?
在JVM抛出之前递归有多深
StackOverflowError?
一旦StackOverflowError投掷,我们可以恢复吗?
class car{
Salon s ;
}
class Salon{
Radio musicsystem ;
}
class Radio{
Button play ;
}
class Button{
String s ;
}
void main(){
car mustang = new car( new Salon( new Radio(new Button ("fight club song"))))
}
Run Code Online (Sandbox Code Playgroud)
我很容易想象有很多新的(新的(新的(新的......))).你有多深?我"直觉地"觉得编译器/ jvm /系统有太多级别的对象可能会很糟糕......
java对深度有限制吗?