深入理解基于栈的字节码执行引擎及JVM底层结构

  1. 生成一个字节码文件
  2. 字节码分析
    1. 一、computer方法:
      1. ==代码 int a=1==
      2. 代码 int b=2
      3. 代码 return a+b
    2. 二、main方法
      1. 代码 Test test = new Test()

在读本文时,可以参考我的另外两篇介绍jvm的博客。

JVM底层结构

Java堆内存介绍及简单性能调优

生成一个字节码文件

首先我们编写一个简单的Java文件

在文件夹中找到这个文件,可以看到只有一个.java 文件

在命令行使用Javac命令,生成.class文件

使用Javap -c命令,生成字节码文件

看到这个乱七八糟的代码,你可能会问,,这tm是什么鬼。

下面通过JVM指令手册从Java底层对字节码进行分析

字节码分析

一、computer方法:

==代码 int a=1==

iconst_1:将int型常量①压入操作数栈

istore_2:将int类型的值存入局部变量①

结合JVM虚拟机内存结构图

首先,给常量a在操作数栈中分配一个内存空间,即iconst_1对应int a

然后,把常量a的值变成1,并存进局部变量表,即istore_2对应a=1

代码 int b=2

iconst_2:将int型常量②压入操作数栈

istore_2:将int类型的值存入局部变量②

同理,很容易理解

代码 return a+b

iload_1:从局部变量①中转载int类型值 即a的值1

iload_2:从局部变量②中装载int类型值 即b的值2

即把变量a的值1给装载出来,放在操作数栈

把变量b的值2给装载出来,放在操作数栈

iadd:执行int类型的加法

即从操作数栈中依次弹出栈顶元素相加,最终生成的结果压回操作数栈 a+b

最后 ireturn:从当前方法返回int

从操作数栈中弹出3

即对应 return 3

二、main方法

代码 Test test = new Test()

new:创建一个对象

我们对比上面的 int a 可以知道,new出来的test 也是一个局部变量,它被存放在main方法对应的栈帧内存区的局部变量表中,
但在jvm底层,对象创建之后放在堆中,

这样我们就可以发现栈和堆之间的一个联系。

那么,这两个东西真的就是一样的嘛?

其实,局部变量表中存放的是堆中对象对应的内存地址,即可以理解为它存放一个指向堆中对象的指针。

到这里,我们就可以通过字节码在jvm底层结构理解整个Java代码的执行过程。

最后还有一个问题

)在这里插入图片描述

在执行main方法时,会跳出去转到computer方法中,在执行完computer方法后,它会再回到main方法中,但是,它回到哪了呢?

方法出口就记录着返回的位置。

同样,程序计数器?

它记录着程序执行的位置,即行数

设想,在Java代码执行时,经常会有多个线程。学过操作系统的就知道,cpu在运行时,经常会发生线程被抢占,被执行的线程挂起。那么,这个线程被挂起之后,它重新运行时,从哪开始呢?

程序计数器就解决了这个问题。


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 2470290795@qq.com

文章标题:深入理解基于栈的字节码执行引擎及JVM底层结构

文章字数:782

本文作者:runze

发布时间:2020-01-28, 18:58:38

最后更新:2020-01-29, 15:15:13

原始链接:http://yoursite.com/2020/01/28/JVM/%E9%80%9A%E8%BF%87Java%E5%AD%97%E8%8A%82%E7%A0%81%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3Java%E6%89%A7%E8%A1%8C%E8%BF%87%E7%A8%8B%E5%8F%8AJVM%E5%BA%95%E5%B1%82%E7%BB%93%E6%9E%84/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录
×

喜欢就点赞,疼爱就打赏