介绍
局部变量表定义为一个数字数组,主要用于存储方法参数和定义在方法体内的局部变量,包括:基本数据类型、对象引用,以及returnAddress。
由于局部变量建立在线程的栈上,是线程的私有数据,因此不存在数据安全问题。
容量大小在编译期确定,保存在方法code属性的maxium local variables数据项中,方法运行期间不会改变。
通过javap -v xx.class 查看:
或者从jclasslib插件查看:
方法嵌套的调用次数由栈和栈帧的大小决定。栈越大,方法嵌套调用的次数越多。
对一个函数而言,参数和局部变量越多,使得局部变量表膨胀,栈帧就越大,进而函数调用就会占用更多的栈空间,导致嵌套调用的次数减小。
**局部变量表中的变量只在当前方法调用中有效。**方法执行时,JVM通过使用局部变量表完成参数值到参数变量列表的传递过程。方法调用结束后,局部变量表随方法栈帧销毁而销毁。
详细解释:
局部变量表中的各个参数:
Start PC:变量作用域的起始点(即声明后的下一行)
Length:作用域的长度(一般情况下,加上start PC就等于code长度 )
关于Slot的理解
局部变量表的存储单元称为slot(变量槽)
32位以内的类型占据一个slot(包括returnAddress类型,和引用类型),64位类型(long、double)两个slot。
32位以内的数据类型都转为int(包括boolean,和C类似)
JVM为局部变量表中的每个slot都分配一个访问索引,通过索引可以访问到局部变量表中指定的局部变量值。(long、double是通过起始索引访问)
当实例方法被调用,方法参数和方法内部局部变量会按照顺序被复制到局部变量表的每一个slot上
如果当前栈由构造方法,或实例方法创建,则对象引用this将会存放在index为0的slot处,其余参数按顺序排列。(静态方法中不存在this引用,直接原因是因为局部变量表中不存在this引用,根本原因是静态方法是属于类对象的,对于类对象的每个实例都应该是一样的,而找不到一个具体的实例来指代this引用)
slot的重复利用
栈帧中的局部变量表的slot是可以重复利用的,如果一个局部变量过了其作用域,那么作用域之后申明的新的局部变量就可能复用过期局部变量的slot,从而节省资源。(这也说明,slot的分配是按照代码顺序的)
比如此处变量b,c在同一个slot。
补充说明*
在栈帧中,与性能调优关系最密切的部分就是局部变量表,
方法执行时,JVM使用局部变量表完成方法的传递
局部变量表中的变量也是重要的垃圾回收根节点,只要被局部变量表中直接或间接引语的对象都不会被回收。