我想确定每个方法在运行时消耗多少堆栈内存。做任务,我已经设计了这个简单的程序,只会迫使StackOverflowError
,推断一个方法的堆栈内存在Java中使用
public class Main {
private static int i = 0;
public static void main(String[] args) {
try {
m();
} catch (StackOverflowError e) {
System.err.println(i);
}
}
private static void m() {
++i;
m();
}
}
打印整数告诉我m()
了多少次调用。我手动设置JVM的堆栈大小(-Xss
VM参数)不同的值(128K,256K,384K),获得以下值:
stack i delta
128 1102
256 2723 1621
384 4367 1644
三角洲是由我计算,它的最后的值线我和现在的。如预期的那样,它是固定的这就是问题所在。据我所知,栈大小的内存增量是128k,这可以产生类似于每个调用80byte的内存使用情况(这看起来很夸张)。
在BytecodeViewer中查找m()
,我们得到一个堆栈的最大深度为2.我们知道这是一个静态方法,并且没有this
参数传递,并且m()
没有参数。我们还必须考虑返回地址指针。所以应该有类似于每个方法调用的3 * 8 = 24个字节(我假设每个变量8个字节,这当然可能完全关闭,是吗?)。即使比这还要多一点,比如说48bytes,我们仍然远离80bytes的值。
我认为这可能与内存对齐有关,但事实是,在这种情况下,我们会有大约64或128字节的值,我会说。
我在64位Windows7操作系统下运行64位JVM。
我做了几个假设,其中一些可能完全关闭。既然如此,我就是耳朵。
在任何人开始问我为什么做这个I must be frank..
这是一些有见地的信息,先生。你可以理论化,为什么每个方法调用似乎需要80个字节? – 2012-02-26 00:53:31
我可以告诉你我自己的JVM实现在Frame结构中保存了什么信息? – Jivings 2012-02-26 01:19:04
@devouredelysium用OpenJDK来源更新了我的答案。 – Jivings 2012-02-26 01:35:43