函数调用方和函数本身就如何传递参数、如何返回结果、如何跳转指令等问题,使用内存来存放这些数据,并且就如何存放和使用这些数据达成一个一致的协议或约定。

这个约定在各种计算机系统中都是类似的,存放这些数据的内存有一个相同的名字,叫

栈是一块内存,顺序是先进后出,类似于一个书堆,越晚放上的书越先拿走。

栈的最下面称为栈底,最上面成为栈顶。

往栈底放数据,称为入栈;往栈顶取数据,成为出栈。

栈一般是从高位地址向低位地址扩展,所以栈底的内存地址是最高的,栈顶的内存地址是最低的

计算机系统主要使用栈来存放函数调用过程中需要的数据,包括参数、返回地址,函数内定义的局部变量也放在栈中。

1
2
3
4
5
6
7
8
9
10
11
public class Sum {
public static int sum(int a,int b) {
int c = a + b;
return c;
}

public static void main(String[] args) {
int d = Sum.sum(1,2);
System.out.println(d);
}
}

上面的代码,概念上:main函数调用了sum函数,计算1+2,然后输出计算结果。

从栈的角度:

(1)当程序在main函数调用Sum.sum函数之前,栈的情况如下表格

地址 内容 函数
0x7FF4
0x7FF8
0x7FFC d main
0x8000 args main

栈主要存放了两个变量args(从控制台接收到的参数)和d。

(2)在程序执行到Sum.sum的函数内部,准备return c之前,栈的情况如下表格。

地址 内容 函数
0x7FEC 3(c) sum
0x7FF0 栈中保存的返回地址 sum
0x7FF4 2(b) sum
0x7FF8 1(a) sum
0x7FFC d main
0x8000 args main

main函数调用Sum.sum时,首先将参数1和2入栈,然后将返回地址入栈,接着跳转到sum函数,在sum函数内部,为局部变量c分配一个空间,而参数变量a和b则直接对应于入栈的数据1和2。在返回之前,返回值3保存到了专门的返回值存储器中。

(3)调用return后,程序会跳转到栈中保存的返回地址,sum函数相关的数据会出战,从而又变回(1)中的状态。

地址 内容 函数
0x7FF4
0x7FF8
0x7FFC d main
0x8000 args main

(4)main的下一条指令是根据函数返回值给变量d赋值,返回值从专门的返回值存储器中获得。

函数中的基本数据类型参数和函数内定义的基本数据类型变量,都分配在栈中。这些变量只有在函数被调用的时候才分配,而且在调用结束后就被释放了。

而数组和对象类型,它们都有两块内存,一块存放实际的内容,一块存放实际内容的地址。实际的内容一般不是分配在栈上的,而是分配在中,但存放地址的空间是分配在栈上的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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[]{2,3,4},然后调用函数max计算0和数组中元素的最大值,最后打印输出最大值。

从栈的角度:

栈-地址 栈-内容 函数 堆-地址 堆-内容
0x7FE8 max(4) max 0x1000 2
0x7EFC 栈中保存的返回地址 max 0x1004 3
0x7FF0 0x1000(arr) max 0x1008 4
0x7FF4 0(min) max
0x7FF8 ret main
0x7FFC 0x1000(arr) main
0x8000 args main

对于数组arr,在栈中存放的是实际内容的地址0x1000,存放地址的栈空间会随着入栈分配,出栈释放。

存放实际内容的堆空间,在函数结束、栈空间没有变量指向它的时候,java系统会自动进行垃圾回收,从而释放这块空间。

栈的空间不是无限的。栈空间过深,系统就会抛出错误——java.lang.StackOverflowError,即栈溢出错误。

  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2021 Silver Shaded
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信