加入收藏 | 设为首页 | 会员中心 | 我要投稿 宁德站长网 (https://www.0593zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长资讯 > 动态 > 正文

面试官竟然问我 Java 虚拟机栈!

发布时间:2021-04-18 15:11:04 所属栏目:动态 来源:互联网
导读:相见恨晚这个词中,我估摸着这名读者在这道面试题前面折戟沉沙了。这么说吧,面试官确实喜欢问 Java 虚拟机方面的知识点,因为很能考察出一名应聘者的真实功底,所以我打算多写几篇这方面的文章,希望能给大家多一点点帮助~ 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。

当然了,局部变量表的大小并不是方法中所有局部变量的数量之和,它与变量的类型和变量的作用域有关。当一个局部变量的作用域结束了,它占用的局部变量表中的位置就被接下来的局部变量取代了。

来看下面这段代码。

  • thod() 方法的局部变量表大小为 1,因为是静态方法,所以不需要添加 this 作为局部变量表的第一个元素;
  • ②的时候局部变量有一个 name,局部变量表的大小变为 1;
  • ③的时候 name 变量的作用域结束;
  • ④的时候局部变量有一个 age,局部变量表的大小为 1;
  • ⑤的时候局 age 变量的作用域结束;

关于局部变量的作用域,《Effective Java》 中的第 57 条建议:

将局部变量的作用域最小化,可以增强代码的可读性和可维护性,并降低出错的可能性。

在此,我还有一点要提醒大家。为了尽可能节省栈帧耗用的内存空间,局部变量表中的槽是可以重用的,就像 method() 方法演示的那样,这就意味着,合理的作用域有助于提高程序的性能。

局部变量表的容量以槽(slot)为最小单位,一个槽可以容纳一个 32 位的数据类型(比如说 int,当然了,《Java 虚拟机规范》中没有明确指出一个槽应该占用的内存空间大小,但我认为这样更容易理解),像 float 和 double 这种明确占用 64 位的数据类型会占用两个紧挨着的槽。

来看下面的代码。

(编辑:宁德站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!