您当前的位置:首页 > 新闻 > 科技

程序员:JVM虚拟机-栈执行原理深入详解

时间:2020-03-12 14:41:30  来源:  作者:

什么是JVM

这个大家都应该很熟悉了吧,JVM不就是虚拟机吗?

JAVA虚拟机本质上就是一个程序,当它在命令行上启动的时候,就开始执行保存在某字节码文件中的指令。

JVM可以说离我们既熟悉又陌生,很多朋友可能在工作中接触不到这块技术,但是在面试往往被问到(概率还蛮大),被问到了自认倒霉,死记硬背是没用的,到头来还是的忘,今天给大家说道说道JVM知识点,我要没让你明白算我输,你可以留言喷我,如果要是可以,你们也给我点个赞成不?

 

初识JVM

程序员:JVM虚拟机-栈执行原理深入详解

 

相信这张图大家都不陌生,这是整个Java体系,其中包括JDK.JRE.JVM三者的关系。

图中可以看得出来JRE包含了JVM,JDK包含了JRE。

从包含的角度就是: JDK是爷爷 JRE是父亲 JVM是儿子(如果觉得列子不太恰当)来看图

程序员:JVM虚拟机-栈执行原理深入详解

 

我们来看代码:

public class App {

private String name;

private Object object = new Object();

/***

* 运算

*/

public int add() {

int a = 1;

int b = 2;

int c = (a + b) * 100;

return c;

}

/**

* 程序入口

*/

public static void main(String[] args) throws InterruptedException {

App app = new App();

int result = app.add();

System.out.println(result);

}

}

程序员:JVM虚拟机-栈执行原理深入详解

 


程序员:JVM虚拟机-栈执行原理深入详解

 

我们运行上述代码输出结果是300,虽然这个代码非常简单,这个时候已经涉及到JVM相关的知识了,在我们学Java基础的时候老师就告诉我们,Java是跨平台的,一次编写到处运行。

那Java是怎么做到跨平台的?继续看下图:

 

通过此图大家就不难发现,我们编译的App.class文件可以在windows操作系统运行也可以在linux系统运行,但是两个系统底层的操作指令是不一样的,为了屏蔽底层指令的细节,起到一个跨平台的作用,JVM功不可没,我们常说Java是跨平台还不如说是Jvm跨平台(JRE运行时跨平台)。那Jvm虚拟机是怎么跨平台的?

JVM底层原理

程序员:JVM虚拟机-栈执行原理深入详解

 

JVM底层由三个系统构成分别是:类加载、运行时数据区、执行引擎。

我们今天重点讲解JVM运行时数据区(栈),其他两块可以关注我之前和后续文章。

我们App.class文件通过类加载子系统从硬盘中读取文件加载到内存中(运行时数据区)。

加载完成之后怎么处理了?(打个比喻 人吃饭 》吃到肚子里》各各器官负责自己工作吸收)

Stack栈

先讲一下其中的一块内存区域虚拟机栈,大家都知道栈是数据结构,也是线程独有的区域,也就是每一个线程都会有自己独立的栈区域。我们运行App.java输出300就靠线程执行得来的结果。是哪个线程执行的?获取线程快照:“main线程”

栈》数据结构》存储内容》先进后出FILO

程序员:JVM虚拟机-栈执行原理深入详解

 

大家都知道每个方法都有自己的局部变量,比如上图中main方法中的result,add方法中的a b c,那么java虚拟机为了区分不同方法中局部变量作用域范围的内存区域,每个方法在运行的时候都会分配一块独立的栈帧内存区域,我们试着按上图中的程序来简单画一下代码执行的内存活动。

程序员:JVM虚拟机-栈执行原理深入详解

 

执行main方法中的第一行代码是,栈中会分配main()方法的栈帧,并存储math局部变量,,接着执行add()方法,那么栈又会分配add()的栈帧区域。

这里的栈存储数据的方式和数据结构中学习的栈是一样的,先进后出。当add()方法执行完之后,就会出栈被释放,也就符合先进后出的特点,后调用的方法先出栈。

栈帧

栈帧内部“数据结构”主要由这几个部分组成:局部变量表、操作数栈、方法出口等信息。

程序员:JVM虚拟机-栈执行原理深入详解

 

说了半天,栈帧到底干嘛用的呀?别急讲这个就会涉及到更底层的原理–字节码。我们先看下我们上面代码的字节码文件。

程序员:JVM虚拟机-栈执行原理深入详解

 

APP.class文件看着像乱码,其实每个都是有对应的含义的,oracle官方是有专门的jvm字节码指令手册来查询每组指令对应的含义的。那我们研究的,当然不是这个。

jdk有自带一个javap的命令,可以将上述class文件生成一种更可读的字节码文件。

程序员:JVM虚拟机-栈执行原理深入详解

 


程序员:JVM虚拟机-栈执行原理深入详解

 

Compiled from "App.java"

public com.App {

public com.App();

Code:

0: aload_0

1: invokespecial #1 // Method java/lang/Object."<init>":()V

4: aload_0

5: new #2 // class java/lang/Object

8: dup

9: invokespecial #1 // Method java/lang/Object."<init>":()V

12: putfield #3 // Field object:Ljava/lang/Object;

15: return

public int add();

Code:

0: iconst_1

1: istore_1

2: iconst_2

3: istore_2

4: iload_1

5: iload_2

6: iadd

7: bipush 100

9: imul

10: istore_3

11: iload_3

12: ireturn

public static void main(java.lang.String[]) throws java.lang.InterruptedException;

Code:

0: new #4 // class com/App

3: dup

4: invokespecial #5 // Method "<init>":()V

7: astore_1

8: aload_1

9: invokevirtual #6 // Method add:()I

12: istore_2

13: getstatic #7 // Field java/lang/System.out:Ljava/io/PrintStream;

16: iload_2

17: invokevirtual #8 // Method java/io/PrintStream.println:(I)V

20: return

}

 

此时的jvm指令码就清晰很多了,大体结构是可以看懂的,类、静态变量、构造方法、add()方法、main()方法。

其中方法中的指令还是有点懵,我们举add()方法来看一下:

Code:

0: iconst_1

1: istore_1

2: iconst_2

3: istore_2

4: iload_1

5: iload_2

6: iadd

7: bipush 100

9: imul

10: istore_3

11: iload_3

12: iretu

 

这几行代码就是对应的我们代码中add()方法中的四行代码。大家都知道越底层的代码,代码实现的行数越多,因为他会包含一些java代码在运行时底层隐藏的一些细节原理。

那么一样的,这个jvm指令官方也是有手册可以查阅的,网上也有很多翻译版本,大家如果想了解可自行百度。

执行流程

设计代码中的部分指令含义:

第一步:压栈

将int类型常量1压入操作数栈

0: iconst_1

就是将1压入操作数栈

程序员:JVM虚拟机-栈执行原理深入详解

 

更正:执行流程过程中灰色背景“操作数栈”应改为“局部变量表”(!!!!!!!!!!)。

程序员:JVM虚拟机-栈执行原理深入详解

 

第二步:存储

将int类型值存入局部变量1

1: istore_1

局部变量1,在我们代码中也就是第一个局部变量a,先给a在局部变量表中分配内存,然后将int类型的值,也就是目前唯一的一个1存入局部变量a

程序员:JVM虚拟机-栈执行原理深入详解

 

第三步:赋值

这两行代码就和前两行类似了。

2: iconst_2

3: istore_2

程序员:JVM虚拟机-栈执行原理深入详解

 

第四步:装载

从局部变量2中装载int类型值

4: iload_1

5: iload_2

这两个代码是将局部变量1和2,也就是a和b的值装载到操作数栈中

程序员:JVM虚拟机-栈执行原理深入详解

 

第五步:加法

执行int类型的加法

6: iadd

iadd指令一执行,会将操作数栈中的1和2依次从栈底弹出并相加,然后把运算结果3在压入操作数栈底。

程序员:JVM虚拟机-栈执行原理深入详解

 

第六步:压栈

将一个8位带符号整数压入栈

7: bipush 100

这个指令就是将100压入栈

程序员:JVM虚拟机-栈执行原理深入详解

 

第七步:乘法

执行int类型的乘法

9: imul

这里就类似上面的加法了,将3和100弹出栈,把结果300压入栈

程序员:JVM虚拟机-栈执行原理深入详解

 

第八步:压栈

将将int类型值存入局部变量3

10: istore_3

这里大家就不陌生了吧,和第二步第三步是一样的,将300存入局部变量3,也就是c

程序员:JVM虚拟机-栈执行原理深入详解

 

第九步:装载

从局部变量3中装载int类型值

11: iload_3

从局表变量3加载到操作数栈

程序员:JVM虚拟机-栈执行原理深入详解

 

第十步:返回

返回int类型值

12: ireturn

我们add方法是被main方法中调用的,所以通过方法出口返回到mian方法中result变量存储方法出口说白了不就是方法执行完了之后要出到哪里,那么我们知道上面add()方法执行完之后应该回到main()方法第三行那么当main()方法调用add()的时候,add()栈帧中的方法出口就存储了当前要回到的位置,那么当add()方法执行完之后,会根据方法出口中存储的相关信息回到main()方法的相应位置。看我图中的红线

程序员:JVM虚拟机-栈执行原理深入详解

 

栈堆关系

main方法中除了result变量还有一个app变量,app变量指向的是一个对象。那对象是怎么存储的?这儿要在说下局表变量表结构:基本类型和引用类型(Java叫引用C C++叫指针)

程序员:JVM虚拟机-栈执行原理深入详解

 

关系就是:

程序员:JVM虚拟机-栈执行原理深入详解

 

通过引用在栈中的app变量引用堆中的App对象

总结

讲到这儿相信大家对JVM栈执行原理是不是熟悉了?如果觉得不错欢迎点赞评论。

程序员:JVM虚拟机-栈执行原理深入详解


Tags:JVM虚拟机   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
什么是JVM这个大家都应该很熟悉了吧,JVM不就是虚拟机吗?Java虚拟机本质上就是一个程序,当它在命令行上启动的时候,就开始执行保存在某字节码文件中的指令。JVM可以说离我们既熟...【详细内容】
2020-03-12  Tags: JVM虚拟机  点击:(110)  评论:(0)  加入收藏
什么是JVM虚拟机JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的...【详细内容】
2019-12-05  Tags: JVM虚拟机  点击:(58)  评论:(0)  加入收藏
▌简易百科推荐
非法购买公民信息、开发人脸认证规避技术&hellip;&hellip;今年年初,广东省公安厅网安部门侦破全国首例破解“青少年防沉迷系统”的新型网络犯罪案件,抓获犯罪嫌疑人13名,查处非...【详细内容】
2021-12-28    人民日报客户端  Tags:数据安全步   点击:(5)  评论:(0)  加入收藏
就在今天,腾讯方面宣布将在2022年1月31日下架企业QQ和营销QQ,其实这一消息的降临并不让笔者意外,因为早在今年的10月28日20点之后,企业QQ和营销QQ就被停止了续费服务。相信很多...【详细内容】
2021-12-27  科技探险家    Tags:企业QQ   点击:(21)  评论:(0)  加入收藏
日前,上海交通大学发布《全球电竞之都评价报告》,对全球15个致力于发展电竞之都的城市进行评价,上海作为中国城市电竞发展的排头兵,其拥有众多优质电竞企业及完整产业集群,因此排...【详细内容】
2021-12-27  经济日报    Tags:电竞   点击:(3)  评论:(0)  加入收藏
为优化网络氛围环境,微博又开始整顿用户信息了。本月月初,微博官方发布公告,要求昵称中带有如“二货”“SB”“瘪三”“娘炮”等明显低俗或侮辱性词汇的用户尽快修改,否则将面临...【详细内容】
2021-12-24  运了个营    Tags:微博   点击:(10)  评论:(0)  加入收藏
昨日谷歌宣布,自2022年12月19日开始停止对OnHub的软件支持,OnHub路由器仍将提供Wi-Fi信号,但用户无法用谷歌Home应用程序管理它。无法更新Wi-Fi网络设置、添加额外的Wifi设备或...【详细内容】
2021-12-22  雷峰网    Tags:Google OnHub   点击:(5)  评论:(0)  加入收藏
IT之家 12 月 20 日消息,百度网盘青春版 iOS 客户端今日晚间率先开启内测,安卓客户端将在稍后内测。使用苹果 iPhone 的IT之家小伙伴可以点此下载内测版,需要先下载 TestFlight...【详细内容】
2021-12-21  IT之家    Tags:百度网盘   点击:(10)  评论:(0)  加入收藏
对于拼车单,是接还是不接,不少网约车司机表示很矛盾。接吧,钱少事多,常常跑了个寂寞,不接吧,车多客少,挑三拣四没饭吃。 在平台大力推广拼车单之下,不少司机迫于生活压力,最终还是打...【详细内容】
2021-12-17  网约车情报分享    Tags:滴滴   点击:(9)  评论:(0)  加入收藏
蓝鲸TMT频道12月16日讯,据饿了么官方微信公众号,近日,在圆桌会上,蓝骑士与平台交流了配送安全问题。饿了么表示,线上将技术手段融入安全防护;线下将持续进行安全培训,并试点智能头...【详细内容】
2021-12-17    金融界  Tags:饿了么   点击:(24)  评论:(0)  加入收藏
开源最前线(ID:OpenSourceTop) 猿妹编译项目地址: https://github.com/restic/restic全球知名代码托管平台 GitHub 今天就重磅发布了今年的年度报告&mdash;&mdash;《2021 年度 O...【详细内容】
2021-12-17  Python部落    Tags:   点击:(9)  评论:(0)  加入收藏
新京报快讯 据中国网络视听节目服务协会网站消息,12月15日,中国网络视听节目服务协会发布了《网络短视频内容审核标准细则》(2021)。中国网络视听节目服务协会组织有关短视频平...【详细内容】
2021-12-16    新京报  Tags:短视频   点击:(11)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条