Java方法执行内存分析

以下程序在JVM中如何执行?

public class testMethod(){
  public static void main(String[] args){
    int a = 10;
    int b = 20;
    int retValue = sumInt(a, b);
    System.out.println("retValue = " + retValue);
  }
  
  public static int sumInt(int i, int j){
    int result = i + j;
    int num = 3;
    int retValue = divide(result, num);
    return retValue;
  }
  
  public static int divide(int x, int y){
    int z = x / y;
    return z;
  }
}

.java文件通过编译后,Class Loader(类加载器)将testMethod.class放到了方法区内存中。

image.png

JVM会默认执行入口函数main,代码执行时JVM在栈内存开辟一块空间供main执行。JVMmain放到了栈内存当中执行,期间发生了压栈(push)动作。栈帧永远指向栈顶元素,栈顶元素是活跃的。

image.png

代码一步一步执行后,逐渐为局部变量开辟内存空间。为main栈开辟了两个名为a、b的内存空间

image.png

当执行到第 5 行的时候也就是int retValue = sumInt(a, b);,调用了sumInt方法。调用的这一瞬间JVM又给sumInt开辟内存。而这时栈帧发生改变,指向了sumInt栈。由于栈帧改变,所以main已暂停执行、被阻塞,现在执行的是栈顶元素,由于栈帧永远指向的是栈顶元素,所以栈顶元素永远处于活跃状态。

image.png

main调用sumInt的时候,在参数传递的时候,实际上传递的是变量中保存的值。将ab变量的值给到sumInt而不是ab。所以sumInt无法操作main里面的局部变量**(无法得到内存地址)**。参数传递的时候是按顺序传递。

image.png

执行到第10行的时候int result = i + j;,这时候需要计算 i + j 的结果给result栈储存。而计算是由中央处理器也就是CPU来执行,CPU将处理后的结果给到result

image.png

程序继续执行,当执行到第12行的时候int retValue = divide(result, num);,又调用 divide,JVMdivide开辟了一块内存空间,发生了压栈动作。逐步开辟x、y、z栈,而z的结果需要通过CPU计算得到。

image.png

而程序遇到return语句后就会强制弹栈(释放内存空间),继续栈顶元素的执行,这时候栈顶元素以及变成sumInt弹栈后代表第12行int retValue = divide(result, num);结束。

image.png

divide 的结果给到retValue

image.png

而往下走遇到return强制弹栈return retValue;sumInt弹栈之后代表着第5行int retValue = sumInt(a, b);结束。

image.png

往下走遇到了System类,这个类实际与其它class(包含testMethod.class)一起被加载到代码区。调用System类里面的println方法后又压栈,执行完成后弹栈,最后main执行完成弹栈。资源全部释放。

代码是逐行执行,从上倒下。

代码编译期不会执行任何计算,JVM执行时计算

栈结构遵循 先进后出,后进先出 的规则

栈内存主要存储的是局部变量

方法调用的时候,在传参的时候,实际上传递的是变量保存的

栈帧永远在栈顶,栈顶元素永远处于活跃状态

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×