说我们是否有这个代码
public static void count(){int i++}
public static void main(String args[])
{
System.out.println("Not calling the count method");
}
JVM什么时候知道多少内存以及何时将count()方法推送到堆栈上?
我认为它是在堆栈上分配的。如果这是真的,那么JVM如何知道将对象方法推送到堆栈上,还是从堆中调用它们。?
假设我们有一个对象并且它有一个方法(非静态)。在main中,我们然后创建一个对象,不要在其上调用任何方法。对象的方法是否仍然被分配到内存中?
java中的静态方法是否在编译时被压入堆栈?来自对象的非静态方法怎么样?
答案 0 :(得分:3)
您对JVM如何执行Java代码存在误解,或者您以错误的方式使用术语。
方法不会被压入堆栈。方法不是从堆中调用的。 (它甚至不清楚你的意思)。在编译时没有任何东西被压入堆栈;调用堆栈仅存在于运行时。
JVM有一个call stack。这意味着无论何时调用方法,JVM都会将返回地址和方法参数放在堆栈上。当方法返回时,弹出返回地址,以便JVM知道继续执行代码的位置。实例方法与static
方法之间没有区别。
方法的字节码只有一个副本。由于方法的字节码在运行时不会改变,因此为类的每个实例复制方法的代码是没有任何意义的(无论方法是否为static
)。
答案 1 :(得分:1)
首先,'stack'一词可用于两种情况:内存管理和调用方法/函数的顺序
例如,当抛出异常时,您可以看到调用堆栈。我会在内存堆栈和堆之间留下一段时间 - 只是内存。方法是一组带有一些额外的本地定义变量的指令(原始类型,其他类似于其余的引用),这就定义了堆栈“frame”的大小,它需要的内存主要取决于这个和一些JVM的东西。删除“静态”时,此区域不会发生任何变化。该方法存在于内存中,当它被调用时,堆栈框架是使用局部变量,参数引用,返回值等创建的。方法“body”很可能(不是100%肯定)复制到任何地方,因为这只是一个要对创建的帧中的数据执行的指令集。
我认为这篇文章可以帮助您理解调用http://www.artima.com/insidejvm/ed2/jvm2.html的方法。静态方法和普通方法在调用并将它们置于堆栈顶部时是相等的。所以回答你的一个问题:方法在调用时会进入堆栈,无论是静态,最终还是常规。
请记住不要混淆内存堆栈和调用堆栈术语。
答案 2 :(得分:0)
当我们谈论堆栈和堆时,我们讨论的是数据存储。
代码是一个完全不同的问题,通常存在于这些存储区域之外。具体来说,在您的体系结构中很可能存在用于在类中声明方法的固定运行时内存开销。此成本不取决于您创建的类的实例数。
换句话说,方法代码的一个副本可以为该类的任意数量的实例提供服务。