前言

为什么要学习JVM?相信好多开发者开头也处于迷惑之中,对于Java虚拟机也是很头疼,大多开发者都会认为,学习JVM无非就是面试。然而,学习JVM并不是为了面试,更是为了深入去理解Java这门语言,笔者大学毕业入坑Java以来也有一年多了,说长也不长,但是在开发的过程中却也是遇到一些性能问题,最后也是由领导解决。个人认为,学习Java虚拟机更是一种基础知识,在开发中才能够深入理解一些细节。

虚拟机和Java虚拟机

虚拟机

虚拟机(Virtual Machine)是一种软件或硬件实体,它模拟了物理计算机的功能,允许在其上运行操作系统和应用程序。虚拟机通常用于隔离不同的计算环境,提供了一种独立于物理硬件的计算平台。

Java虚拟机

Java虚拟机(Java Virtual Machine,JVM)是一种软件虚拟机,特别为执行Java程序而设计。JVM是Java平台的核心组件之一,它负责将Java字节码翻译成可以在特定计算机上运行的本地机器代码。Java程序员编写的Java代码首先被编译成字节码,然后由JVM执行。这种方式使Java程序具有跨平台的特性,因为只需要在不同平台上实现JVM,就可以在各种操作系统上运行相同的Java程序。

JVM的主要任务包括字节码加载、解释执行或即时编译、垃圾回收、内存管理等。它还提供了各种标准库和API,用于支持Java程序的运行和互动。不同的Java虚拟机实现可以适应不同的硬件和操作系统,但它们都遵循Java虚拟机规范(Java Virtual Machine Specification),以确保Java程序的跨平台性。

JVM的位置

Java虚拟机试运行在操作系统之上的,和硬件是没有直接交互的。
在Java 生态系统中的三个关键组件:JDK(Java Development Kit)、JRE(Java Runtime Environment)和 JVM(Java Virtual Machine)
① JDK(Java Development Kit)

JDK是用于Java应用程序的开发工具包。它包括Java编译器(javac)、Java虚拟机(JVM),以及各种开发工具和库,如调试器、性能分析工具、API文档生成工具等。JDK是开发人员用于创建、编译和调试Java应用程序的关键工具,它使开发者能够编写Java源代码并将其编译成Java字节码。JDK的结构包括bin目录,其中包含编译器和其他命令行工具,以及lib目录,其中包含Java类库和运行时支持。

② JRE(Java Runtime Environment)

JRE是用于运行Java应用程序的运行时环境。它包括Java虚拟机(JVM)和Java类库(Java API),允许用户执行已编译的Java应用程序,而不需要进行开发。JRE没有开发工具,因此不包含编译器或其他开发相关的工具。JRE的结构包括bin目录,其中包含用于运行Java应用程序的JVM可执行文件,以及lib目录,其中包含Java类库

三者中,JDK 包含 JRE,而 JRE 包含 JVM。JDK 提供了完整的 Java 开发和运行时环境,适用于开发人员,而 JRE 提供了用于运行 Java 应用程序的环境,适用于普通用户或生产环境。 JVM 是在 JDK 和 JRE 中共享的核心组件,负责执行 Java 应用程序。

*JVM的整体结构

简单介绍HotSpot VM

HotSpot VM(HotSpot Virtual Machine)是Oracle(以前是Sun Microsystems)开发的 Java 虚拟机的一种实现,它是Java平台上最广泛使用的虚拟机之一。HotSpot VM在性能和可移植性方面表现出色,它是Java应用程序的运行时引擎,负责将Java字节码翻译成本地机器代码并执行程序。

HotSpot VM是Oracle JDK(Java Development Kit)的一部分,也是许多其他Java发行版的基础,包括OpenJDK。由于其卓越的性能和稳定性,HotSpot VM一直是广泛使用的Java虚拟机之一,特别适用于生产环境和要求高性能的Java应用程序。

整体结构介绍

未命名文件 (1).png
对于上图,这里简单介绍一下
首先是Java类通过编译成class文件,在用过类加载器加载到内存中。

类加载是Java虚拟机(JVM)的一个关键组件,负责将Java字节码文件加载到内存中并转换为可执行的类。类加载器的主要任务是查找和加载类文件,确保在程序运行时可以访问所需的类。类加载器的工作使Java的动态性成为可能,允许在运行时加载和卸载类。

接着看这个第二层,运行时的数据区,这里包含了方法区、Java栈、本地方法栈、堆、程序计数器

方法区是存储类信息、常量、静态变量以及编译后的字节码的地方,包括类的结构信息、方法和字段描述,以及运行时常量池。
是Java程序中用于存储对象实例的区域。
是每个线程独有的,用于存储方法调用、局部变量以及方法返回值。
本地方法栈与栈类似,但它存储的是Java程序调用本地方法(使用JNI,Java Native Interface)时的信息。
程序计数器是当前线程执行的字节码指令的位置计数器。

总结

方法区和堆:这两个是多线程共享的
Java栈、本地方法栈和程序计数器:这是每个线程都独有一份

最后看第三层,这一层是和操作系统和硬件交互的重要组件。执行引擎,这是Java虚拟机核心组件之一,他是负责执行Java字节码,将Java字节码解释成底层平台的机器码,或者通过即时编译器(Just-In-Time Compiler,JIT)将字节码编译成本地机器代码以提高性能。本地方法接口是Java虚拟机提供的机制,允许Java代码与本地代码(通常是用C或C++编写的)进行交互,在Java中就是呗native修饰的接口方法。本地方法库是包含本地方法的动态链接库(通常是.so文件或.dll文件),用C或C++编写。

Java代码执行流程

Java代码的执行流程可以分为一下几个步骤:

  • 编写Java代码:编写一个xxx.java的文件。
  • 编译源代码:使用Java编译器,将Java源文件编译成xx.class的字节码文件(通常是使用javac)。
  • Java虚拟机:在Java虚拟机(JVM)中,其负责加载字节码文件并将其转换为可执行代码。在类加载过程中还有一些操作,类加载、链接、初始化等等。
  • 执行程序:一旦类加载完成并且程序初始化完成,JVM开始执行程序。
  • 运行时垃圾收集:JVM会定期检查不再被引用的对象,并进行垃圾回收以释放内存资源
  • 程序结束:程序执行完main方法或遇到异常时,程序将结束执行。

未命名文件 (2).png

JVM的生命周期

Java虚拟机的生命周期简单来说就是三个阶段:启动、执行、退出。JVM的生命周期确保了Java程序的安全加载、初始化和执行,以及资源管理和垃圾回收。这一过程是Java跨平台性的关键,因为它将Java程序从特定硬件平台解耦,使其能够在不同操作系统上运行。

虚拟机启动

Java虚拟机在启动的时候是通过类加载器创建一个初始类来完成。在这一阶段,类加载器加载Java字节码文件,并对其进行验证、准备、解析和初始化等操作,接着链接,包括验证类的正确性、为静态变量分配内存和解析符号引用。然后初始化,在这个阶段,JVM执行类的静态初始化代码,初始化静态变量。

虚拟机执行

JVM进入运行阶段,开始执行程序,通常从main方法开始。程序在运行过程中可以加载、链接、初始化其他类,并执行程序逻辑。同时,JVM的垃圾回收器定期检查不再被引用的对象,进行垃圾回收。这个Java程序在Java虚拟机中就是一个进程。

虚拟机退出

在程序执行完成或出现严重错误时,JVM会进入终止阶段,可以执行清理操作。最后,如果某个类不再被引用,并且没有实例存在,JVM可能会进行卸载,释放内存。

常见虚拟机

常见的虚拟机,每种的实现通常都是针对不同的需求,比如sun classic vm、exact vm、jrockit、j9等等。以下笔者通过网络查阅到一些的简单介绍。

在Java生态系统中,有几个常见的Java虚拟机(JVM)实现,每个实现通常针对不同的用例和需求。以下是一些常见的JVM实现:

  • Oracle HotSpot JVM:这是Oracle公司的官方JVM实现,广泛用于生产环境。它以高性能和优化而闻名,是许多企业应用程序的首选JVM。
  • OpenJDK:OpenJDK是Oracle的开放源JVM实现,也是许多其他JVM的基础。它提供了Java开发工具和库,并被许多Linux发行版采用作为默认JVM。
  • IBM J9 JVM:IBM的J9虚拟机是WebSphere应用服务器和其他IBM产品的一部分。它专注于嵌入式和企业级应用。
  • Apache Harmony:虽然已经终止,但Apache Harmony曾是一个Apache项目,旨在创建一个免费的、开放源的JVM实现。虽然它不再维护,但它仍然被某些项目和研究用途使用。
  • GraalVM:GraalVM是Oracle开发的一款全栈虚拟机,支持多种语言,包括Java、JavaScript、Python等。它具有高性能和多语言互操作性,适用于各种应用场景。
  • Azul Zing:Azul Zing是专门针对大规模、高性能Java应用程序而设计的JVM。它包括C4垃圾收集器,可显著降低垃圾回收停顿时间。
  • SAP JVM:SAP JVM是针对SAP应用的JVM实现,优化了SAP系统的性能和稳定性。

这些JVM实现在性能、垃圾回收策略、支持的平台和工具等方面存在差异,开发人员可以根据其应用程序的需求选择最适合的JVM。总的来说,Java虚拟机的多样性为Java生态系统的健康发展提供了重要的选择。

总结

本章就是学习一下Java虚拟机的概念,为了对Java虚拟机有个简单的认识。总之我们知道的JVM有许多,但是我们经常遇到的就是Oracle HotSpot JVM ,Java虚拟机的主要任务包括字节码加载、解释执行或即时编译、垃圾回收、内存管理等。它还提供了各种标准库和API,用于支持Java程序的运行和互动。不同的Java虚拟机实现可以适应不同的硬件和操作系统。