Java中方法执行过程中内存的变化


前言

  想要真正掌握Java,内存分析是必要的,一旦掌握内存的分配,在程序没有运行之前我们就可以很精准的预测到程序的执行结果。这篇文章要讲解的是程序的内存,例如:代码片段被存储在什么位置?方法调用的时候,在哪开辟内存空间等等。

一、JVM内存结构

下图是JVM标准内存结构图。
在这里插入图片描述  目前,我们只关注**“栈”和“方法区”
  Java程序开始执行的时候先通过类加载器子系统找到硬盘上的字节码(.class文件),然后将其加载到JVM的方法区当中,开始调用main方法,main方法被调用的瞬间,会给main方法在“栈”内存中分配所属的活动空间,此时发生压栈动作,main方法的活动空间处于栈底。
  由于栈的特点是
先进后出**,所以最先调用的方法(最先压栈)一定是最后结束的(最后弹栈)。所以main方法最先被调用,那么它一定是最后一个结束的。换句话说,main方法结束了,程序也就结束了。

二、分析程序的内存变化

public class MethodTest {
    
    
    public static void main(String[] args) {
    
    
        System.out.println("main begin");
        m1();
        System.out.println("main over");
    }
    public static void m1(){
    
    
        System.out.println("m1 begin");
        m2();
        System.out.println("m1 over");
    }
    public static void m2(){
    
    
        System.out.println("m2 begin");
        System.out.println("m2 over");
    }
}

运行结果如下:

在这里插入图片描述
  我们来分析一下该段代码的内存变化,如下图所示:

在这里插入图片描述采用文字描述如下:

  1. 类加载器将class文件加载到方法区
  2. 开始调用main方法,在栈内存中给main方法分配空间,开始执行main方法,输出“main begin”
  3. 调用m1()方法,在栈内存中给m1()方法分配空间,此时m1()方法处于栈顶,具有活跃权,输出“m1 begin”
  4. 调用m2()方法,在栈内存中给m2()方法分配空间,此时m2()方法处于栈顶,具有活跃权,输出“m2 begin”,继续输出“m2 over”
  5. m2()方法执行结束,内存释放,弹栈
  6. m1()方法这时处于栈顶,具备活跃权,输出“m1 over”
  7. m1()方法执行结束,内存释放,弹栈
  8. main()方法处于栈顶,具备活跃权,输出“main over”
  9. main()方法执行结束,内存释放,弹栈
  10. 栈空,程序结束

总结

  方法体中代码的执行是有顺序的,必须遵循自上而下的顺序依次逐行执行,也就是说当前行代码必须执行结束,下一行代码才能执行,不能跳跃执行。那么,我们再结合栈的数据结构一起联系起来思考,采用栈数据结构的原因就很清晰了,只有采用这种先进后出的栈的数据结构才能保证代码的执行顺序。

猜你喜欢

转载自blog.csdn.net/m0_46988935/article/details/110132407