剑指JVM:虚拟机实践与性能调优
上QQ阅读APP看书,第一时间看更新

4.3 局部变量表

4.3.1 局部变量表简介

局部变量表也称为局部变量数组或本地变量表。局部变量表定义为一个数字数组,主要用于存储方法参数和定义在方法体内的局部变量,这些数据类型包括各类基本数据类型、对象引用(reference)以及returnAddress类型。对于基本数据类型的变量,则直接存储它的值,对于引用类型的变量,则存的是指向对象的引用。

由于局部变量表是建立在线程的栈上,是线程的私有数据,因此不存在数据安全问题。

局部变量表所需的容量大小是在编译期确定下来的,并保存在方法的Code属性的maximum local variables数据项中。在方法运行期间是不会改变局部变量表的大小的。

方法嵌套调用的次数由栈的大小决定。一般来说,栈越大,方法嵌套调用次数越多。对一个方法而言,它的参数和局部变量越多,使得局部变量表越膨胀,它的栈帧就越大,以满足方法调用所需传递的信息增大的需求。进而调用方法就会占用更多的栈空间,导致其嵌套调用次数就会减少。

局部变量表中的变量只在当前方法调用中有效。在方法执行时,虚拟机通过使用局部变量表完成参数值到参数变量列表的传递过程。当方法调用结束后,随着方法栈帧的销毁,局部变量表也会销毁。

下面通过代码清单4-6演示局部变量表,注意,在查看局部变量表之前需要编译好代码,即编译为class文件。

代码清单4-6 查看局部变量表

通过IntelliJ IDEA安装Jclasslib Bytecode Viewer插件可以查看局部变量表。安装好插件以后,单击“View”选项,选择“Show Bytecode With Jclasslib”选项,如图4-13所示。

图4-13 使用工具查看局部变量表

上面的操作结果如图4-14所示,LocalVariableTable用来描述方法的局部变量表,在class文件的局部变量表中,显示了每个局部变量的作用域范围、所在槽位的索引(Index列)、变量名(Name列)和数据类型(J表示long型)。参数值的存放总是从局部变量表的索引(Index)为0开始,到变量总个数减1的索引结束,可以看到,main()方法中总共存在4个变量,分别是args、test、num和num1,Index的初始值为0,最终值为3。

图4-14 class文件的局部变量表

如图4-15所示,在“Code”选项下的“Misc”列中Maximum local variables值为5,可是明明局部变量表中变量的数量只有4个,为什么局部变量表大小是5呢?这是因为局部变量表最基本的存储单元是slot,long类型的数据占两个slot(见4.3.2节),所以需要加1。

图4-15 局部变量表大小