函数调用的基本原理

函数调用引入的问题

  • 参数如何传递?
  • 函数如何知道返回到什么地方?
  • 函数结果如何传给调用方?

解决方案

    • 存放函数调用过程中需要的数据,包括参数、返回地址,以及函数内定义的局部变量等的内存叫做栈
    • 顺序是先进后出,最下面的称为栈底,最上面的称为栈顶。
    • 往栈里放数据称为入栈,从栈顶拿出数据通常称为出栈。栈底的内存地址是最高的,栈顶的是最低的。
    • 返回值可能放在栈中,但它使用的栈和局部变量不完全一样,有的系统使用 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 系统会自动进行垃圾回收,从而释放这块空间。

关联文章


文章作者: huan
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明来源 huan !
  目录