如何增加 Java 堆栈大小?堆栈、大小、Java

2023-09-07 02:45:46 作者:无毒不丈夫i

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

I asked this question to get to know how to increase the runtime call stack size in the JVM. I've got an answer to this, and I've also got many useful answers and comments relevant to how Java handles the situation where a large runtime stack is needed. I've extended my question with the summary of the responses.

最初我想增加 JVM 堆栈大小,这样程序就可以在没有 StackOverflowError 的情况下运行.

Originally I wanted to increase the JVM stack size so programs like runs without a 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));
  }
}

对应的配置设置是java -Xss... 命令行标志,其值足够大.对于上面的程序 TT,它在 OpenJDK 的 JVM 上是这样工作的:

The corresponding configuration setting is the java -Xss... command-line flag with a large enough value. For the program TT above, it works like this with OpenJDK's JVM:

$ javac TT.java
$ java -Xss4m TT

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

One of the answers has also pointed out that the -X... flags are implementation dependent. I was using

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)

也可以只为一个线程指定一个大堆栈(如何在其中一个答案中查看).建议在 java -Xss... 上这样做,以避免为不需要它的线程浪费内存.

It is also possible to specify a large stack only for one thread (see in one of the answers how). This is recommended over java -Xss... to avoid wasting memory for threads that don't need it.

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

I was curious how large a stack the program above exactly needs, so I've run it n increased:

-Xss4m 可以满足 fact(1 << 15)-Xss5m 可以满足 fact(1 << 17)-Xss7m 可以满足 fact(1 << 18)-Xss9m 可以满足 fact(1 << 19)-Xss18m 可以满足 fact(1 << 20)-Xss35m 可以满足 fact(1 << 21)-Xss68m 可以满足 fact(1 << 22)-Xss129m 可以满足 fact(1 << 23)-Xss258m 可以满足 fact(1 << 24)-Xss515m 可以满足 fact(1 << 25)

从上面的数字看来,Java 似乎为上面的函数使用了每个堆栈帧大约 16 个字节,这是合理的.

From the numbers above it seems that Java is using about 16 bytes per stack frame for the function above, which is reasonable.

上面的枚举包含 can be enough 而不是 is enough,因为堆栈要求不是确定性的:使用相同的源文件和相同的 -Xss... 有时会成功,有时会产生 StackOverflowError.例如.对于 1