目录
线程作为系统运算调度的最小单位,在JVM中线程的行为体现就是函数调用,函数调用中数据的传递就是通过Java栈,Java栈顾名思义有着和数据结构中“栈”相似的属性,后进先出,出栈入栈,栈中保存的是栈帧,当JVM发生函数调用时,就会有一个栈帧被压入Java栈,当函数调用结束后,再从栈中弹出栈帧,当前正在执行的函数其对应的栈帧位于栈顶处,且保存有当前函数的局部变量表和栈数据区(保存一些中间结果等数据)。在函数返回,也就是有栈帧要从Java栈中弹出时,正常的情况是函数通过return返回,此时栈帧正常弹出,如果函数调用出现问题无法正常返回,则抛出异常,举个例子:我们每一次函数调用时都会对Java栈进行入栈操作,栈空间是一定的,随着不断入栈操作,例如递归函数调用,栈空间变得越来越小,最后达到最大可用深度时,就会抛出栈溢出异常,所以有时我们递归函数调用过程中出现的“StackOverflowError”,就是栈空间因为某些原因被占满了导致的。
局部变量表
函数对应的栈帧中有一个局部变量表,里面保存了调用函数的局部变量,参数等,这些参数和变量是跟着函数走的,只在当前函数调用中有效,函数调用结束后,栈帧就会弹出Java栈,局部变量表也就随之被销毁。来看一个简单的例子:
draw()方法中有3个入参和3个局部变量,它们都是int数据类型,一个占用24个字节内存空间,在32位操作系统中每4个字节为一个字,所以在局部变量表中,函数draw()的局部变量一共占6个字。