前置知识

阅读本文需要对以下知识有所了解:

* 栈

* 汇编

* Java 基础

* 逆波兰表达式(有学过的同学阅读本文毫无障碍)

引子

基于寄存器的设计模式

就我们所熟知的x86或arm指令集来说,其对数据的操作都是基于寄存器。例如,要对两个数执行加法操作则需要将这两个数分别送入两个寄存器再执行加法操作,这也符合我们对于编程语言认知,更加易于理解。

基于栈的设计模式

基于栈的设计模式则是将数据存放在栈中,在需要使用的时候将栈顶的数据出栈,并执行相应的操作。

举例来说,在JVM中 执行 a = b + c 的字节码执行过程中操作数栈以及局部变量表的变化如下图所示。

局部变量表中存储着a、b、c 三个局部变量,首先将b和c分别入栈

将栈顶的两个数出栈执行加法操作,并将结果保存至栈顶,之后将栈顶的数出栈赋值给a

一个简单的例子

在上一节中我们了解了栈与局部变量表是如何配合完成一次加法操作的,这一节我们将对局部变量表进行深入的研究。

如何查看局部变量表?

我们可以通过反编译class文件的方式查看局部变量表,不过在这里更加推荐使用IDEA的jclasslib插件(直接搜就有)查看字节码,因为其设计更加人性化,更加友好。

实例方法中的局部变量表

我们知道在实例方法中我们可以直接访问实例的成员变量或函数,而不需要通过this来引用,这是如何实现的?

像这种问题直接动手写个测试类,反编译一下结果自然就清晰了。

首先来一个简单的类

public class T {

    private int a = 0;

    public void add(int b,int c){
a = b + c;
}
}

其次,将该类选中,然后在view中选中showbytecode with jclasslib

效果如下:

选择我们关注的Methods中add方法,注意观察图中高亮的部分

原来,JVM在编译代码的时候,偷偷在局部变量表中添加了一个this引用(很明显this保存的实例的引用),这也是我们为什么可以在方法中访问实例中的成员变量的原因,证明如下

图中节码的简要解释如下:

0)aload_0 将this的引用入栈 (aload_0即将局部变量表中索引为0的引用压到操作数栈中)

1)iload_1 将参数b入栈 (将局部变量中的索引为1的整数压到操作数栈中)

2)iload_2 将参数c入栈

此时栈的内容有(0为栈顶)

0.c

1.b

2.this

3)iadd 将栈顶的两个数相加,并将结果保存至栈顶,此时栈的内容为

0.b+c

1.this

4). putfield 将栈顶的两个值出栈,第一个值(b+c)赋值给第二个值(this)的对应的成员变量(是的,没错即使是赋值也要执行两次出栈操作)

putfield的说明如下(注意图中的高亮部分):



地址:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.putfield

结论

基于栈的指令集系统可以很方便的做到平台无关性(x86、arm),但也降低了性能,这也是为啥Java性能比C低原因。(操作寄存器快,还是操作栈快?哈哈哈哈哈哈哈哈哈哈哈)

最新文章

  1. 【转】Weblogic的集群
  2. JavaScript添加、查找、删除元素的一个实例
  3. http协议读书笔记3-Web服务器
  4. 关于在TabBar 中添加按钮,并通过block 或代理在控制器中实现响应
  5. VR问题无关方向,VR全景为您领航,全景智慧城市已势不可当
  6. 【Access2007】解救被阉割的truncate
  7. css盒子模型(3)
  8. 常用SQL Server命令(持续) | Commonly used SQL Server command list (Cont')
  9. 吴恩达机器学习笔记58-协同过滤算法(Collaborative Filtering Algorithm)
  10. [Swift]LeetCode238. 除自身以外数组的乘积 | Product of Array Except Self
  11. Python内置函数(60)——staticmethod
  12. react-router-dom v^4路由、带参路由的配置
  13. yii2 getter
  14. OpenStack-Neutron-VPNaaS-测试和使用
  15. Java_myBatis入门写法
  16. windows下pem转ppk
  17. PasteDeploy部署Pecan API 服务
  18. 解决远程登陆Linux误按ctrl+s锁屏
  19. 学校网站UI设计分析
  20. Python学习---django多对多之Djanog默认表学习

热门文章

  1. Zimg—轻量级图片服务器搭建利器
  2. java接口自动化(一) - 接口自动化测试整体认知 - 开山篇(超详解)
  3. 【小家Spring】聊聊Spring中的数据绑定 --- DataBinder本尊(源码分析)
  4. 常用的re模块的正则匹配的表达式
  5. 一些学习js的算法题目
  6. Android 常用 Manager的总结
  7. mysqli_query 的定义和用法
  8. File文件类
  9. Openstack中用keypair生成和访问虚机的方法
  10. spark streaming 接收kafka消息之五 -- spark streaming 和 kafka 的对接总结