【发布时间】:2012-03-14 23:48:49
【问题描述】:
我正在尝试确定每个方法在运行时消耗多少堆栈内存。为了完成这个任务,我设计了这个简单的程序,它只会强制StackOverflowError,
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
delta 是我计算出来的,是最后一行的 i 和当前的 i 之间的值。正如预期的那样,它是固定的。这就是问题所在。据我所知,堆栈大小的内存增量为 128k,这会产生类似于每次调用 80 字节的内存使用量(这似乎被夸大了)。
在 BytecodeViewer 中查找 m(),我们得到堆栈的最大深度为 2。我们知道这是一个静态方法,并且没有 this 参数传递,并且 m() 没有参数。我们还必须考虑返回地址指针。所以每个方法调用应该使用 3 * 8 = 24 个字节(我假设每个变量使用 8 个字节,这当然可能完全关闭。是吗?)。即使比这多一点,比如说 48bytes,我们离 80bytes 的值还很远。
我认为这可能与内存对齐有关,但事实是,在这种情况下,我会说,我们的值大约为 64 或 128 字节。
我在 64 位 Windows7 操作系统下运行 64 位 JVM。
我做了几个假设,其中一些可能完全不成立。既然如此,我全都听好了。
在有人开始问我为什么要这样做之前I must be frank..
【问题讨论】: