【从浅入深JVM】1、JVM是什么,JVM整体结构

谈到 Java,大家肯定都知道,它是一种编程语言。那么,Java 这种编程语言,又是怎么被开发出来的呢?它为什么能跨平台运行呢?我们进行 Java 编程时,需要什么样的 Java 环境呢?带着这些问题,我们来逐渐解开它的神秘面纱。

JDK 体系结构

我们在进行 Java 编程时,首先第一个动作便是搭建 Java 运行环境。

打开 Java 官网,下载 Java,可以看到,Java 帮我们提供了不同平台的下载包,这个下载包叫做:JDK。JDK 是什么呢?

JDK 用来编译、调试 Java 程序的开发工具包,我们的开发、运行环境,由 JDK 支撑。之所以 Java 能够跨平台运行,是因为 Java 官方提供了多平台的 JDK,使得这些不同平台的 JDK 都能够编译我们编写的 Java 代码。

JDK 在 Java 语言中如此重要,那么它的体系结构是怎么样的呢?

谈到 JDK 的体系结构,就不得不上一张老演员了。如下图:

图片

JDK 由 JavaLanguage、Tools、JRE 三部分组成。其中,JavaLanguage 表示的是程序员编写的 Java 代码,Tools 是一些指令工具集,如 java 用于执行字节码程序,javac 用于编译字节码文件。JRE 是 Java 的运行环境,包括了 JavaAPI 和 Java 虚拟机(JVM),Java 虚拟机就是来运行 Java 程序的一个虚拟环境。

了解了 JDK 的体系结构,那么,Java 是如何运行起来的呢?

Java 运行原理

简单来说,Java 的运行过程如下图:

图片

  1. 用户编写 Java 程序:人看懂的字符
  2. 使用 javac 编译 Java 程序:计算机看懂的字符
  3. 提交 Java 程序到虚拟机
  4. 虚拟机运行 Java 程序
    为了更容易理解这个过程,我们写一个简单的案例。

编写一个 Java 程序

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("HelloWorld");
    }
}

编译 Java 程序

javac HelloWorld.java 

图片

运行 Java 程序

运行 Java 程序的时候,会自动把我们要运行的字节码文件提交到 Java 虚拟机。所以第 3 步和第 4 步是合起来的。

(注:如果 HelloWorld 带了包名,运行时需要在根目录下运行带包名的类。)

java HelloWorld
# 
java org.example.HelloWorld

通过这个简单的案例,可以看出,我们的 Java 程序是如何运行起来的,主要难点是在编译和运行阶段,这一部分是由 Java 官方提供的,如果我们要去优化我们的 Java 程序,那么我们就必须要去了解官方是如何运行我们的程序的。

那么,Java 虚拟机是什么呢?它是如何运行 Java 程序的呢?

什么是 JVM

前面提到了 Java 虚拟机(JVM),那么,什么是 Java 虚拟机呢?

我们知道,计算机首先是由系统(windows、linux、mac)来协调各个应用程序去调用硬件请求,而不同的系统,运行的应用程序是不同的,linux 不能够运行 windows 下的应用程序,windows 也不能运行 linux 下的应用程序,Java 虚拟机就是一个应用程序,它针对 windows、linux、mac 都提供了不同的程序,这个不同程序(不同系统上的 jvm),它能够完美执行同一套 Java 程序。所以 Java 虚拟机是部署在不同的操作系统上的一个可以运行 Java 程序的应用程序。

图片

面试重点:Java 语言跨平台特性。

我们了解了 Java 虚拟机是什么,接下来,我们重点来说说,Java 虚拟机是如何工作的。

JVM 整体结构

网上大部分都资料都把 Java 虚拟机的体系结构说成内存模型,其实这有点儿瑕疵的,Java 虚拟机的主要组成部分有类加载器、运行时数据区、执行引擎、本地库接口。如下图:

图片

ClassLoader:就是我们前面说的,把 Java 字节码文件提交到 Java 虚拟机的过程中,使用到的。它负责加载字节码文件(class 文件),class 文件在文件开头有特殊的文件标识,CLassLoader 只负责加载带有特殊标识的 class 文件,它会把加载好的 class 文件放入到运行时数据区。

执行引擎:类加载器把 class 文件加载以后,会把 class 文件中的相关指令放在运行时数据区,执行引擎会从运行时数据区把相关的指令取出,然后进行解释后交给操作系统去进行执行。

本地库接口:本地库接口即不同操作系统提供给 Java 语言的指令调用接口,Java 提供的 API 最终都会去通过本地库接口去进行调用。

运行时数据区:运行时数据区,就是我们都很熟悉的内存模型。

了解了 JVM 的核心组成接口后,那么是不是发现,Java 程序的整个运行原理,也就很清晰了呢?总结下,Java 程序的运行原理大体是:先将 Java 程序编译成 Java 虚拟机可识别的字节码文件,然后类加载器负责将编译好的字节码文件加载到 Java 虚拟机内存(进程内存),Java 虚拟机中有一个执行引擎会从运行时数据区中取出字节码文件中的指令,然后翻译成操作系统可识别的指令,并交给操作系统去进行执行。通过不断的取出指令执行指令的过程,完成整个 Java 程序的运行。

发表回复