用一段简单代码看JVM的执行过程

我们的JVM是通过模拟计算机达到一个计算机应有的功能,jvm和实体机一样,有一套自己的指令集,凡是符合规范的class文件都可以被JVM执行,jvm基本分为四个部分,我喜欢能画图尽量不码字:
用一段简单代码看JVM的执行过程_第1张图片
我们在eclipse或者idea写好的Java文件就是通过这么一个先编译后运行的过程,其中被红线围起来的就是JVM。
其中程序员最关心的就是中间最大的一块包括五个部分:方法区、堆、本地方法区、pc寄存器和每次创建一个线程都会产生的栈桢,我们也称这块区域叫运行时数据区。
我们通过一段小的代码看看执行引擎是怎么的执行过程:

package cn.com;

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

main方法创建了一个线程,它的字节码指令分别为:

用一段简单代码看JVM的执行过程_第2张图片

这时整个运行时数据区状态如下图:

用一段简单代码看JVM的执行过程_第3张图片

栈桢包括存储局部变量区、操作数栈、动态连接、方法出入口等信息, 栈的操作基本原则是先进后出,所以1先从局部变量区入栈,2后入栈,idd指令就是将1,2弹出栈相加将结果保存在局部变量区后再次入栈,在开始方法执行前,pc存储器的指针是第一条指令的地址,局部变量区和操作数栈都没有数据,第1条到第4条指令就是将常数1,2分别存储到局部变量区

用一段简单代码看JVM的执行过程_第4张图片

第5和第6条命令又将常数1,2再次入栈:

用一段简单代码看JVM的执行过程_第5张图片

第7条指令将栈顶两个元素弹出相加再次入栈:

用一段简单代码看JVM的执行过程_第6张图片

同理,第8条指令将10入栈,当前pc寄存器的地址是9:

用一段简单代码看JVM的执行过程_第7张图片

然后将第10步将10和3同时弹出相乘,并把结果压入栈中:
用一段简单代码看JVM的执行过程_第8张图片

第10条指令完成后,第11条指令将30这个结果存入局部变量区。
用一段简单代码看JVM的执行过程_第9张图片
第12条指令是return,这个方法执行完后对应的这些线程私有的部件都会被jvm回收,局部变量区的所有值将全部释放,pc寄存器会被销毁,在Java栈中与这个方法对应的栈桢将会消失,到此这一段代码的执行过程就演示完了,看起来也没有想象中那么复杂。这里我开始有一个问题:为什么JVM要采取基于栈的结构方式,变量计算时直接从内存中拿不是节约几次入栈操作吗?
后来查资料来看一是为了保证在没有或者很少有寄存器的机器上也能保证Java代码的正确性,这是JVM平台无关性的前提。

你可能感兴趣的:(JVM)