为什么我的堆栈溢出错误会在 518669 之后发生?

发布于 2024-08-24 12:42:16 字数 312 浏览 14 评论 0原文

我创建了一个java程序来计数无穷大:

class up {

    public static void up (int n) {
        System.out.println (n) ;    
        up (n+1) ;
}

    public static void main (String[] arg) {
        up (1) ;

}
}

我实际上并没有期望它能到达那里,但我注意到有点奇怪的是它每次都停在相同的数字:518669

这有什么意义数字? (或者我想这个数字+1)。

I created a java program to count up toward infinity:

class up {

    public static void up (int n) {
        System.out.println (n) ;    
        up (n+1) ;
}

    public static void main (String[] arg) {
        up (1) ;

}
}

I didn't actually expect it to get there but the thing that i noticed that was a bit curious was that it stopped at the same number each time: 518669

What is the significance of this number? (or of this number +1 i suppose).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

甜警司 2024-08-31 12:42:16

除了显然 518669 乘以该方法的堆栈大小等于系统上的总可用堆栈空间之外,该数字本身没有什么意义。

There is little significance to that number itself other than apparently 518669 multiplied by whatever the stack size is for that method equals the total available stack space on your system.

遥远的绿洲 2024-08-31 12:42:16

该特定值并不重要,它是您本地设置的结果。重复获得相同的值是重要且可预测的。

您的程序在此时持续崩溃,因为每次运行程序时,Java 虚拟机都会以相同的参数启动,然后执行相同的操作,直到堆栈空间耗尽。

您可以更改两者,并更改结果。

您可以通过传递 -Xss 标志来更改 JVM 可用的最大堆栈大小,例如:

java -Xss4096k MyClass

在我的机器上,使用默认启动参数,我在 10,518 后耗尽堆栈空间递归调用。我认为我的设置的默认值是 1024k。

如果我将最大堆栈大小设置为 4096k,如上所述,我可以在堆栈溢出之前获得 50,777 次递归调用。

您还可以向方法添加更多操作或不同的操作,每次调用消耗更多空间并更改可能的调用次数。

如果我将语句 MyClass myClass = new MyClass(); 添加到 println 语句之后的代码(每次调用 MyClass 的本地实例)中,则在溢出之前可以进行的调用次数将从10,518 到 9,709,因为每次调用时都会存储对 MyClass 实例的引用。

That specific value isn't significant, it's a result of your local setup. That you get the same value repeatedly is significant and predictable.

Your program crashes consistently at that point because each time you're running your program, the Java Virtual Machine starts with the same parameters and then performs the same actions until the stack space is gone.

You can change both, and change the result.

You can change the max stack size available to your JVM by passing a -Xss flag, for example:

java -Xss4096k MyClass

On my machine, with my default startup parameters, I run out of stack space after 10,518 recursive calls. I think the default is 1024k for my setup.

If I set the max stack size to 4096k as above, I can get 50,777 recursive calls before a stack overflow.

You can also add more operations, or different operations to your method, consume more space per call and change the number of possible invocations.

If I add the statement MyClass myClass = new MyClass(); to the code (a local instance of MyClass per call) after your println statement, the number of calls I can make before an overflow goes down from 10,518 to 9,709 as on each call a reference to an instance of MyClass has be stored.

梦归所梦 2024-08-31 12:42:16

分配给调用堆栈的内存量是有限的。每次运行应用程序时,内存量都是相同的。因此它每次都会在同一个位置停止计数,因为堆栈内存不足。

至于你的侧面,我会以

class up 
{
    public static void up(int n) 
    {
        System.out.println(n);    
        up(n + 1);
    }

    public static void main(String[] arg) 
    {
        up(1);

    }
}

这种方式格式化这样,当你的块开始和结束时就更清楚了。

You have a finite amount of memory allocated to the call stack. It is the same amount of memory each time you run the application. So it stops counting in the same place each time, because you are out of stack memory.

As to your aside, I would format in this mannor

class up 
{
    public static void up(int n) 
    {
        System.out.println(n);    
        up(n + 1);
    }

    public static void main(String[] arg) 
    {
        up(1);

    }
}

This way it is much more clear when your blocks begin and end.

听,心雨的声音 2024-08-31 12:42:16

为了回答你的问题,方法的右大括号通常与方法的开头对齐。因此,在您的情况下,与 public 的“p”在同一列中。

To answer your aside, the close brace of a method is generally aligned with the start of the method. So in your cases here, in the same column as the 'p' of public.

锦欢 2024-08-31 12:42:16

数字 518669 没有什么特别之处,只不过这是在用完可用内存之前可以容纳的堆栈帧数。

这里没有理由使用递归——您应该简单地使用 while 循环。

There is nothing special about the number 518669 except that this is how many stack frames you can fit in your available memory before you run out.

There is no reason to use recursion here -- you should simply use a while loop instead.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文