以下程序在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
放到了方法区内存中。
JVM
会默认执行入口函数main
,代码执行时JVM
在栈内存开辟一块空间供main
执行。JVM
将main
放到了栈内存当中执行,期间发生了压栈(push)动作。栈帧永远指向栈顶元素,栈顶元素是活跃的。
代码一步一步执行后,逐渐为局部变量开辟内存空间。为main
栈开辟了两个名为a、b
的内存空间
当执行到第 5 行的时候也就是int retValue = sumInt(a, b);
,调用了sumInt
方法。调用的这一瞬间JVM
又给sumInt
开辟内存。而这时栈帧发生改变,指向了sumInt
栈。由于栈帧改变,所以main
已暂停执行、被阻塞,现在执行的是栈顶元素,由于栈帧永远指向的是栈顶元素,所以栈顶元素永远处于活跃状态。
在main调用sumInt的时候,在参数传递的时候,实际上传递的是变量中保存的值。将a和b变量的值给到sumInt而不是a和b。所以sumInt无法操作main里面的局部变量 (无法得到内存地址)。参数传递的时候是按顺序传递。
执行到第10行的时候int result = i + j;
,这时候需要计算 i + j
的结果给result
栈储存。而计算是由中央处理器也就是CPU来执行,CPU将处理后的结果给到result
程序继续执行,当执行到第12行的时候int retValue = divide(result, num);
,又调用 divide
,JVM
给divide
开辟了一块内存空间,发生了压栈动作。逐步开辟x、y、z
栈,而z
的结果需要通过CPU计算得到。
而程序遇到return
语句后就会 强制弹栈(释放内存空间),继续栈顶元素的执行,这时候栈顶元素以及变成sumInt
,弹栈后代表第12行int retValue = divide(result, num);
结束。
将divide
的结果给到retValue
而往下走遇到return
强制弹栈return retValue;
。sumInt
弹栈之后代表着第5行int retValue = sumInt(a, b);
结束。
往下走遇到了System
类,这个类实际与其它class(包含testMethod.class
)一起被加载到代码区。调用System
类里面的println
方法后又压栈,执行完成后弹栈,最后main
执行完成弹栈。资源全部释放。
代码是逐行执行,从上倒下。
代码编译期不会执行任何计算,JVM执行时计算
栈结构遵循 先进后出,后进先出 的规则
栈内存主要存储的是局部变量
方法调用的时候,在传参的时候,实际上传递的是变量保存的值
栈帧永远在栈顶,栈顶元素永远处于活跃状态