JVM执行引擎工作方式


声明:本文转载自https://my.oschina.net/chenxuanli/blog/1790628,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

每当创建一个新的线程时,JVM会为这个线程创建一个JAVA栈,同时会为这个线程分配一个PC寄存器,并且这个PC寄存器会指向这个线程的第一行可执行代码。每当调用一个新方法时会在这个栈上创建一个新的栈帧数据结构,这个栈帧会保留这个方法的一些元信息,如在这个方法中定义的局部变量、一些用来支持常量池的解析、正常方法返回及异常处理机制等等。JVM在调用某些指令时可能需要使用到常量池中的一些常量,或者是获取常量代表的数据或者这个数据指向的实例化对象,而这些信息都存储在所有线程共享的方法区和Java堆中(JDK7起方法区PermGen永久代逐渐被MetaSpace取代)。

Java执行部件图如下图所示。 输入图片说明

那么JVM具体是如何执行的呢?以下面的代码为例:

public class Math{     public static void main(String[] args){         int a = 1;         int b = 2;         int c = (a + b) * 10;     } } 

对应到执行引擎的各执行部件如下图所示。 输入图片说明

图中,指令是Java代码经过javac编译后得到的JVM指令,PC寄存器指向下一条该执行的指令地址,局部变量区存储函数运行中产生的局部变量,栈存储计算的中间结果和最后结果。

我们解释一下这十二条指令,分别是常数1入栈,将栈顶元素移入本地变量1存储,常数2入栈,将栈顶元素移入本地变量2存储,本地变量1入栈,本地变量2入栈,弹出栈顶两个元素相加然后结果入栈,将10入栈,栈顶两个元素弹出并相乘然后结果入栈,栈顶元素移入本地变量3存储,返回。 上图是地址为9的指令执行完毕后的状态,PC寄存器指向地址10。地址为9的指令将栈顶两个元素弹出并相乘然后将结果入栈,所以操作栈中计算结果30为栈顶元素。执行地址10的指令后,30被保存在本地变量3中,故局部变量区地址为3的区块将保存30。

在Java程序的执行过程中,栈操作是无处不在的。所以我们可以想到,在Java中,我们不仅可以自定义栈数据结构从而显式调用栈,还可以通过JVM的运行机制隐式调用栈。可能你已经想到了,我们可以使用递归函数的形式,来利用JVM的栈已达到栈这种后入先出的数据结构在计算中获得的效果。

当A函数调用B函数时,JVM会为B函数在栈中压如一个新的栈帧,并将这个栈帧设为当前栈帧,函数B运行结束时,将栈帧弹出撤销,将B的返回结果压入栈的栈顶,PC寄存器恢复调用栈的下一条指令地址。然后A函数执行完毕,执行return命令如果当前线程对应的栈中没有了栈帧,这个Java栈也将会被JVM撤销。

本文发表于2018年04月06日 22:38
(c)注:本文转载自https://my.oschina.net/chenxuanli/blog/1790628,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 1930 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1