我的JVM系列文章,彻底搞定JVM!

​JVM(一)JVM架构介绍​​​​JVM(二)运行时数据区​​​​JVM(三)类加载机制​​​​JVM(四)垃圾回收机制​

JVM的作用和为什么要学习它

JVM(Java Virtual Machine,Java 虚拟机),JVM 可以理解为是一个虚拟出来的计算机,具备着计算机的基本运算方式,它主要负责将 Java 程序生成的字节码文件解释成具体系统平台上的机器指令。

我们知道,Java 语言的一个非常重要的特点就是与平台的无关性,这个特性也要归功于 JVM。一般的高级语言如果要在不同的平台上运行,至少需要编译成不同的目标代码(因为不同的平台具有不同的指令集和数据结构)。而 Java 语言使用 JVM 屏蔽了与具体平台相关的信息,只需要将源码通过编译程序编译成在 JVM 上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。而 JVM 在执行字节码时,把字节码解释成具体平台上的机器指令执行,如下图:

JVM(一)JVM架构介绍_字节码

所以,JVM最重要的作用就是屏蔽操作系统的差异,使Java 可以一次编译到处运行(并不限于Java语言,只要能生成.class文件的语言均可)。

学习JVM的目的

  • 面试重灾区,必须搞定它才能收割offer;
  • 工作中的性能优化等离不开它;
  • 了解底层实现,拥有完备的知识体系;

JVM的位置

在Java平台的结构中, 可以看出,Java虚拟机(JVM) 处在核心的位置,是程序与底层操作系统和硬件无关的关键,如下图:

JVM(一)JVM架构介绍_java_02

JVM的下方是移植接口,移植接口由两部分组成:适配器和Java操作系统, 其中依赖于平台的部分称为适配器;JVM 通过移植接口在具体的平台和操作系统上实现;在JVM 的上方是Java的基本类库和扩展类库以及它们的API, 利用Java API编写的应用程序(application) 和小程序(Java applet) 可以在任何Java平台上运行而无需考虑底层平台, 就是因为有Java虚拟机(JVM)实现了程序与操作系统的分离,从而实现了Java 的平台无关性。

JVM、JRE和JDK的关系

JDK (Java Development Kit) 是 Java 语言的软件开发工具包(SDK),是支持 Java 程序开发的最小环境。在 JDK 的安装目录下有一个 jre 目录,里面有两个文件夹 bin 和 lib,在这里可以认为 bin 里的就是 JVM,lib 中则是 JVM 工作所需要的类库,而 JVM 和 lib 合起来就称为 JRE。

JRE(Java Runtime Environment,Java 运行环境),包含 JVM 标准实现及 Java 核心类库,是支持 Java 程序运行的标准环境。由于 JRE 是运行环境,并不是一个开发环境,所以没有包含任何开发工具(如编译器和调试器)。

JVM(Java Virtual Machine,Java 虚拟机),JVM 可以理解为是一个虚拟出来的计算机,具备着计算机的基本运算方式,它主要负责将 Java 程序生成的字节码文件解释成具体系统平台上的机器指令。让具体平台如 windows 运行这些 Java 程序。

三者的关系如下:

JVM(一)JVM架构介绍_jvm_03

JVM的组成

JVM 主要由四大部分组成:ClassLoader(类加载器),Runtime Data Area(运行时数据区,内存分区),Execution Engine(执行引擎),Native Interface(本地库接口),如下图:

JVM(一)JVM架构介绍_java_04


类加载器(ClassLoader)

ClassLoader 负责加载字节码文件即 class 文件,class 文件在文件开头有特定的文件标示,并且 ClassLoader 只负责class 文件的加载,至于它是否可以运行,则由 Execution Engine 决定。

执行引擎(Execution Engine)
执行引擎,也叫 Interpreter。Class 文件被加载后,会把指令和数据信息放入内存中,Execution Engine 则负责把这些命令解释给操作系统,即将 JVM 指令集翻译为操作系统指令集。

本地库接口(Native Interface)
负责调用本地接口的。他的作用是调用不同语言的接口给 JAVA 用,他会在 Native Method Stack 中记录对应的本地方法,然后调用该方法时就通过 Execution Engine 加载对应的本地 lib。原本多用于一些专业领域,如JAVA驱动,地图制作引擎等,现在关于这种本地方法接口的调用已经被类似于Socket通信,WebService等方式取代。

运行时数据区(Runtime Data Area)
Runtime Data Area 是存放数据的,分为五部分:Stack(虚拟机栈),Heap(堆),Method Area(方法区),PC Register(程序计数器),Native Method Stack(本地方法栈)。(几乎所有的关于 Java 内存方面的问题,都是集中在这块)

JVM工作流程

程序在执行之前先要把java代码转换成字节码(class文件),jvm首先需要把字节码通过一定的方式 类加载器(ClassLoader) 把文件加载到内存中 运行时数据区(Runtime Data Area) ,而字节码文件是jvm的一套指令集规范,并不能直接交个底层操作系统去执行,因此需要特定的命令解析器 执行引擎(Execution Engine) 将字节码翻译成底层系统指令再交由CPU去执行,而这个过程中需要调用其他语言的接口 本地库接口(Native Interface)来实现整个程序的功能。