函数调用的基本原理
函数调用引入的问题
- 参数如何传递?
- 函数如何知道返回到什么地方?
- 函数结果如何传给调用方?
解决方案
- 栈
- 存放函数调用过程中需要的数据,包括参数、返回地址,以及函数内定义的局部变量等的内存叫做栈
- 顺序是先进后出,最下面的称为栈底,最上面的称为栈顶。
- 往栈里放数据称为入栈,从栈顶拿出数据通常称为出栈。栈底的内存地址是最高的,栈顶的是最低的。
- 返回值可能放在栈中,但它使用的栈和局部变量不完全一样,有的系统使用 CPU 内的一个存储器存储返回值
- 堆
- 对象类型(引用类型)都有两块内存,一块存放指向实际内容的地址,另一块存放实际的内容。存放地址的空间是分配在栈上的,实际的内容空间分配在堆中。
堆栈角度分析函数执行
//main函数新建了一个数组,然后调用函数max计算0和数组中元素的最大值
public class ArrayMax {
public static int max(int min, int[] arr) {
int max = min;
for(int a : arr){
if(a>max){
max = a;
}
}
return max;
}
public static void main(String[] args) {
int[] arr = new int[]{2,3,4};
int ret = max(0, arr);
System.out.println(ret);
}
}
堆栈分析
流程剖析:从 main 方法开始,依次入栈
- 入栈 int 数组 arr,对象类型,分配栈内存和堆内存
- 入栈 int 变量 ret,调用方法 max 开始比较
- 入栈 int 变量 min=0
- 入栈 int 变量 max=min
- 循环语句调用 int 数组 arr
- 比较并修改 max 变量的值
- 比较结束,返回 max = 4
- ret 赋值等于 4,输出 ret
- 基本数据类型的变量只有在函数被调用的时候才分配,而且在调用结束后就被释放了。
- 对于数组 arr,在栈中存放的是实际内容的地址 0x1000,存放地址的栈空间会随着入栈分配,出栈释放。
- 存放实际内容的堆空间在栈空间没有变量指向它的时候,Java 系统会自动进行垃圾回收,从而释放这块空间。
关联文章
- 上一篇:函数的用法