面试官竟然问我 Java 虚拟机栈!
相见恨晚”这个词中,我估摸着这名读者在这道面试题前面折戟沉沙了。这么说吧,面试官确实喜欢问 Java 虚拟机方面的知识点,因为很能考察出一名应聘者的真实功底,所以我打算多写几篇这方面的文章,希望能给大家多一点点帮助~ Java 虚拟机以方法作为基本的执行单元,“栈帧(Stack Frame)”则是用于支持 Java 虚拟机进行方法调用和方法执行的基本数据结构。每一个栈帧中都包含了局部变量表、操作数栈、动态链接、方法返回地址和一些额外的附加信息(比如与调试、性能手机相关的信息)。之前的文章里有提到过这些概念,并做了一些简单扼要的介绍,但我觉得还不够详细,所以这篇重点要来介绍一下栈帧中的这些概念。 1)局部变量表局部变量表(Local Variables Table)用来保存方法中的局部变量,以及方法参数。当 Java 源代码文件被编译成 class 文件的时候,局部变量表的最大容量就已经确定了。 我们来看这样一段代码。按理说,局部变量表的最大容量应该为 2 才对,一个 age,一个 name,为什么是 3 呢? 当一个成员方法(非静态方法)被调用时,第 0 个变量其实是调用这个成员方法的对象引用,也就是那个大名鼎鼎的 this。调用方法 write(18),实际上是调用 write(this, 18)。 点开 Code 属性,查看 LocalVaraiableTable 就可以看到详细的信息了。 0 个是 this,类型为 LocalVaraiablesTable 对象;第 1 个是方法参数 age,类型为整形 int;第 2 个是方法内部的局部变量 name,类型为字符串 String。 当然了,局部变量表的大小并不是方法中所有局部变量的数量之和,它与变量的类型和变量的作用域有关。当一个局部变量的作用域结束了,它占用的局部变量表中的位置就被接下来的局部变量取代了。 来看下面这段代码。
关于局部变量的作用域,《Effective Java》 中的第 57 条建议: 将局部变量的作用域最小化,可以增强代码的可读性和可维护性,并降低出错的可能性。 在此,我还有一点要提醒大家。为了尽可能节省栈帧耗用的内存空间,局部变量表中的槽是可以重用的,就像 method() 方法演示的那样,这就意味着,合理的作用域有助于提高程序的性能。 局部变量表的容量以槽(slot)为最小单位,一个槽可以容纳一个 32 位的数据类型(比如说 int,当然了,《Java 虚拟机规范》中没有明确指出一个槽应该占用的内存空间大小,但我认为这样更容易理解),像 float 和 double 这种明确占用 64 位的数据类型会占用两个紧挨着的槽。
来看下面的代码。 (编辑:宁德站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |