JVM概述

2021-03-28  本文已影响0人  布拉德老瓜

1.write once, run anywhere的基石

java语言有一个很重要的特性:一次编写,到处运行。即我们编写的代码,能够在不同的操作系统平台上运行。这里就引发出一个问题,不同的操作系统有不同的硬件实现和指令集,同一份代码如果要在这些不同的机器上运行,那么就要将这些代码翻译成与机器指令集对应的二进制文件,才能保证运行结果的一致性。

java使用虚拟机去屏蔽操作系统的差异性,其原理如图所示。我们编写的Java程序在被编译后,以class文件的形式被存放在磁盘、内存、网络...中,然后由jvm进行加载,并解释执行。字节码文件相当于是对我们所编写程序的二进制描述,但他并不能被操作系统直接执行,而是由jvm解释成对应系统的指令,再进行执行。因此java程序虽然会被编译,但仍属于解释型语言。另一方面,现在的JVM为了效率,都有一些JIT优化。它又会把.class的二进制代码编译为本地的代码直接运行,所以,它也不完全是一门解释型语言。


处处运行的基石

2. JDK,JRE,JVM的关系

JDK是支持java语言开发的最小支持环境,包含了java语言,工具即其api,JRE。
JRE是运行时环境,能够支持java语言的运行。包含了JVM和Java核心类库,但不包含开发工具(将.java编译成.class文件的编译器、调试器等)
JVM是将.class文件加载到内存并解释执行的组件,显然它是java体系的核心部件。


组件关系

3. JVM的功能及指令集基础

JVM中实现了对java指令的加载、解释、执行。
其指令集是基于栈的架构而非基于寄存器的架构。也就是说,指令的操作数依赖于操作数栈,而非操作数地址。
举个例子说明:

public class AddA {
    public static void main(String[] args) {
        int a = 2;
        int b = 3;
        int c = a + b;
    }
}
...
对应的字节码指令
0 iconst_2 //2入栈
1 istore_1 //2出栈,并存放到局部变量表1位置
2 iconst_3  //3入栈
3 istore_2 //3出栈,并存放到局部变量表1位置
4 iload_1  //从局部变量表1位置读取操作数并入栈
5 iload_2  //从局部变量表2位置读取操作数并入栈
6 iadd  // 弹栈并相加,将结果5压入操作数栈
7 istore_3 // 5出栈并存放到局部变量表3位置
8 return  //方法返回

而基于寄存器的计算2+3则如图


基于寄存器:2+3

之所以java指令要依据栈来实现,主要原因是不同平台cpu架构不同,设计为基于寄存器的话,难以实现跨平台。

上一篇 下一篇

猜你喜欢

热点阅读