堆栈框架占用的大小

时间:2013-11-20 11:09:02

标签: java memory stackframe

Java堆栈为每个方法调用创建新帧,但是这个帧是否在堆栈上占用内存?

澄清我的问题:

public void oneWay()
{
  System.out.println("start");
  get1();
}

private void get1()
{
  System.out.println("get1");
  get2();
}

private void get2()
{
  System.out.println("get2");
}

输出与:

相同
public void anotherWay()
{
  System.out.println("start");
  System.out.println("get1");
  System.out.println("get2");
}

但是第二个代码片段在堆栈上占用更多内存还是相等?简而言之,堆栈帧会记忆吗?

编辑:堆叠帧占用多少内存? Sun是否有任何规范,现在是Oracle?

3 个答案:

答案 0 :(得分:4)

是的,很自然。这就是为什么如果嵌套太深,你会得到堆栈溢出的原因。如果您发现需要为线程设置更大(或更小)的堆栈,则可以使用-Xss命令行开关来修改堆栈大小。

specification似乎为实现提供了很大的自由,所以总而言之,你不能真正依赖堆栈帧大小。

答案 1 :(得分:1)

您可以将当前线程堆栈上的堆栈帧数计算为:

Thread.currentThread().getStackTrace().length

在您的情况下,在get2中获取此值会比直接在oneWay(大于2)中获得更大的值。确切的值取决于您调用的代码oneWay中的位置。 虽然其他一些编程语言不一定为每个函数调用创建一个堆栈帧,但Java总是如此。 JVM规范在§2.6中明确指出“每次调用方法时都会创建一个新帧”。以后“框架从Java虚拟机堆栈分配”。因此在Java中,每个方法调用都会设置一个堆栈帧,每个堆栈帧都会占用堆栈上的内存。即使在调用无效的函数时,虚拟机也需要一定量的内存来跟踪堆栈帧本身。

答案 2 :(得分:1)

Inside the Java Virtual Machine中所述,

  

堆栈帧有三个部分:局部变量,操作数堆栈和帧数据。局部变量和操作数堆栈的大小(以单词计量)取决于每个单独方法的需要。这些大小在编译时确定,并包含在每个方法的类文件数据中。帧数据的大小取决于实现。

     

当Java虚拟机调用Java方法时,它会检查类数据以确定方法在局部变量和操作数堆栈中所需的字数。它为方法创建了适当大小的堆栈帧,并将其推送到Java堆栈。