在 Java 中推断方法的堆栈内存使用情况
我正在尝试确定每个方法在运行时消耗了多少堆栈内存。为了完成这项任务,我设计了这个简单的程序,它将强制一个,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();
}
}
打印一个整数告诉我被调用了多少次。我手动将JVM的堆栈大小(VM参数)设置为不同的值(128k,256k,384k),得到以下值:m()
-Xss
stack i delta
128 1102
256 2723 1621
384 4367 1644
delta是由我计算的,它是最后一行的i和当前行之间的值。正如预期的那样,它是固定的。问题就在这里。据我所知,堆栈大小的内存增量是128k,这会产生每次调用80字节的内存使用量(这似乎被夸大了)。
在BytecodeViewer中查找,我们得到堆栈的最大深度为2。我们知道这是一个静态方法,没有参数传递,也没有参数。我们还必须考虑返回地址指针。所以每个方法调用应该使用3 * 8 = 24个字节(我假设每个变量8个字节,这当然可能完全关闭了。是吗?)。即使它比这多一点,比如说48字节,我们仍然离80bytes值还很远。m()
this
m()
我认为这可能与内存对齐有关,但事实是,在这种情况下,我们的值大约是64或128字节,我会说。
我在64位Windows7操作系统下运行64位JVM。
我做了几个假设,其中一些可能完全关闭了。既然如此,我全都洗耳恭听。
在有人开始问我为什么要这样做之前,我必须坦率。