5

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)是否有任何规范?

4

3 回答 3

4

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

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

于 2013-11-20T11:11:05.427 回答
3

如在Java 虚拟机内部中所述

栈帧由三部分组成:局部变量、操作数栈和帧数据。以字为单位的局部变量和操作数堆栈的大小取决于每个单独方法的需要。这些大小在编译时确定并包含在每个方法的类文件数据中。帧数据的大小取决于实现。

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

于 2013-11-21T10:38:53.823 回答
1

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

Thread.currentThread().getStackTrace().length

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

于 2013-11-20T11:16:56.583 回答