Java 堆栈帧采用的大小

Java 堆栈帧采用的大小,java,memory,stack-frame,Java,Memory,Stack Frame,Java堆栈为每个方法调用创建新的框架,但是这个框架会占用堆栈上的内存吗 就我的问题作出澄清: public void oneWay() { System.out.println("start"); get1(); } private void get1() { System.out.println("get1"); get2(); } private void get2() { System.out.println("get2"); } 其输出与以下内容相同: pub

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)有什么规范吗?

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


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

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

Thread.currentThread().getStackTrace().length
在您的情况下,在
get2
中获取该值将比直接在
单向中获取该值(大于2)得到更大的值。确切的值取决于您在代码中单向调用
的位置。
尽管其他一些编程语言不一定为每个函数调用创建堆栈框架,但Java总是这样。JVM规范在§2.6中明确指出,“每次调用一个方法时都会创建一个新的帧。”之后的“帧是从Java虚拟机堆栈中分配的”。因此,在Java中,每个方法调用都会建立一个堆栈帧,每个堆栈帧都会占用堆栈上的内存。即使在调用不执行任何操作的函数时,虚拟机也需要一定数量的内存来跟踪堆栈帧本身。

如中所述

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

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


我只是想补充一点,这一切并不意味着你应该削弱你的设计,用更少的模块和更多的代码。由于模块化设计,内存不太可能耗尽的确,在99%的情况下,堆栈溢出是因为程序尝试无限递归而发生的任何想法,一帧需要多少内存?@Batty有点小把戏,最大深度似乎是1024(至少对我而言),如果纯帧内存是主堆栈,那么这可能是第一个问题memory@Batty视情况而定。它包括局部变量和参数,因此,对于每一个方法调用都是不一样的。@ DaveNeWtNo.No,但是有编程语言不一定在每个方法调用中设置一个堆栈帧,例如C++。@ DaveNewton我把这个句子改写为你的地址。谢谢你张贴。这意味着调用函数时,堆栈帧的大小是恒定的,不能调整大小,对吗?