尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

JVM基础入门:从运行机制到主流虚拟机实现

JVM基础入门:从运行机制到主流虚拟机实现 JVM基础入门从运行机制到主流虚拟机实现JVM基础入门从运行机制到主流虚拟机实现一、什么是 JVM二、为什么 Java 能够跨平台三、JVM 的三大核心功能1. 解释和运行字节码四、JVM 的内存管理能力1. 自动分配内存2. 自动垃圾回收五、即时编译为什么 Java 并不是单纯解释执行1. 普通代码的执行2. 热点代码优化六、解释器与 JIT 为什么要同时存在七、Java 虚拟机规范八、JVM 不只能运行 Java九、常见的 JVM 实现十、HotSpot JVM十一、HotSpot 名字是怎么来的十二、HotSpot 的发展十三、JDK、JRE、JVM 的关系十四、整体知识结构十五、核心知识点总结1. JVM 是什么2. Java 程序如何运行3. Java 为什么能够跨平台4. JVM 有哪些核心功能5. 什么是 JIT6. JVM 是否只能运行 Java7. 最常见的 JVM 是什么十六、面试常见问题Q1JVM 是什么Q2Java 为什么可以跨平台Q3JVM 的主要作用有哪些Q4JVM、JDK、JRE 有什么区别Q5Java 是解释型语言还是编译型语言十七、结语JVM基础入门从运行机制到主流虚拟机实现一、什么是 JVMJVM 的全称是Java Virtual Machine中文通常称为Java 虚拟机。从本质上来说JVM 就是一个运行在操作系统上的程序它最核心的职责是加载并运行 Java 字节码文件。Java 程序并不是直接由操作系统执行的而是需要经过编译和 JVM 运行两个阶段。整体过程可以概括为Java 源代码 ↓ javac 编译 ↓ .class 字节码文件 ↓ JVM 加载并执行 ↓ 机器指令 ↓ CPU 执行例如我们编写一个HelloWorld.javapublicclassHelloWorld{publicstaticvoidmain(String[]args){System.out.println(Hello JVM);}}首先通过 Java 编译器javac HelloWorld.java得到HelloWorld.class这个.class文件并不是 Windows、Linux 或 macOS 能够直接执行的机器指令而是一套统一格式的Java 字节码指令。真正负责读取并执行这些字节码指令的就是 JVM。二、为什么 Java 能够跨平台Java 中有一个非常经典的特点Write Once, Run Anywhere也就是一次编写到处运行。实现这一特性的关键就在 JVM。Java 源代码经过编译以后并不会直接生成某一种 CPU 或操作系统对应的机器指令而是生成统一的.class字节码。例如Windows JVM ↓ Java代码 → 字节码 → Linux JVM ↓ macOS JVM不同操作系统提供对应版本的 JVM。JVM 再负责把相同的 Java 字节码转换成当前系统能够执行的机器指令。因此真正跨平台的是Java 字节码而 JVM 本身并不是跨平台的。Windows 有 Windows 对应的 JVMLinux 有 Linux 对应的 JVM不同平台上的具体实现有所区别。可以简单理解成Java 字节码负责统一 JVM 负责适配平台这也是 Java 跨平台能力的底层基础。三、JVM 的三大核心功能JVM 并不仅仅是一个简单的字节码执行程序。从整体来看它主要承担三类重要工作JVM ├── 解释和运行 ├── 内存管理 └── 即时编译下面分别来看。1. 解释和运行字节码Java 编译器生成的.class文件保存的是字节码指令。这些指令 CPU 无法直接识别因此需要 JVM 将它们转换成 CPU 能够执行的机器指令。简单理解Java 字节码 ↓ JVM 解释执行 ↓ 机器指令 ↓ CPU例如字节码中可能存在iconst_1 iconst_2 iadd这些属于 JVM 指令。JVM 会根据当前 CPU 架构将这些指令转换成真正的机器指令并执行。四、JVM 的内存管理能力Java 开发中我们通常不会像 C/C 一样频繁手动申请和释放内存。例如创建一个对象UserusernewUser();程序员只需要创建对象并不需要明确告诉操作系统给这个对象分配多少字节内存这些工作由 JVM 完成。JVM 的内存管理主要可以分成两个方面。1. 自动分配内存程序运行过程中会产生大量数据例如UserusernewUser();StringnameTom;int[]arraynewint[100];这些对象和数据都需要占用内存。JVM 会负责为它们分配合适的运行空间。2. 自动垃圾回收当某些对象已经不再使用时如果一直占据内存就会造成大量内存浪费。例如UserusernewUser();usernull;如果这个User对象已经没有任何有效引用在满足一定条件之后JVM 可以通过垃圾回收机制将其占用的内存重新释放。这个过程通常称为Garbage Collection简称GC因此 Java 程序员一般不需要手动释放对象内存。不过自动管理内存并不意味着 Java 不会出现内存问题。实际生产环境中仍然可能出现内存泄漏 内存溢出 频繁 Full GC GC 停顿时间过长 堆内存使用异常所以 JVM 内存管理也是 Java 性能优化中的重点。五、即时编译为什么 Java 并不是单纯解释执行如果 JVM 每次运行代码都重新解释一次字节码执行效率就会受到影响。为了解决这个问题现代 JVM 引入了一个非常重要的机制JIT全称Just In Time Compiler也就是即时编译器。1. 普通代码的执行代码第一次执行时可以由解释器进行处理字节码 ↓ 解释器 ↓ 机器指令 ↓ 执行解释执行的优点是启动快不需要提前进行大量编译。但缺点也比较明显同一段代码每次执行都需要进行解释如果某段代码被执行几十万甚至几百万次这种方式效率就比较低。2. 热点代码优化JVM 在程序运行过程中会监控代码执行情况。如果发现某段代码被频繁执行这段代码就可能成为热点代码此时 JIT 编译器会介入。大致过程可以理解为字节码 ↓ 发现热点代码 ↓ JIT 编译 ↓ 生成优化后的机器指令 ↓ 保存到内存 ↓ 后续直接执行机器指令也就是说当热点代码再次执行时不需要继续逐条解释。这就是 JVM 提升 Java 程序运行效率的重要手段之一。六、解释器与 JIT 为什么要同时存在可能会产生一个疑问既然 JIT 编译后的执行效率更高为什么不把所有代码都直接编译成机器指令因为编译本身也是有成本的。如果程序刚启动就把所有代码全部编译大量代码编译 ↓ 消耗 CPU ↓ 增加内存占用 ↓ 启动速度下降而实际上很多代码可能只运行一次甚至根本不会执行。因此 JVM 采用了一种更加灵活的策略普通代码 ↓ 解释执行 频繁执行的热点代码 ↓ JIT 编译优化两者结合可以兼顾启动速度 长期运行性能这也是现代 JVM 性能较高的重要原因之一。七、Java 虚拟机规范JVM 并不是只有一种实现。理论上任何厂商都可以开发自己的 Java 虚拟机。但是如果每家公司都按照自己的方式实现那么 Java 程序的兼容性就很难保证。因此需要一套统一的标准Java Virtual Machine Specification也就是Java 虚拟机规范该规范规定 JVM 在实现过程中需要遵循的一系列规则包括Class 字节码文件格式 类和接口的加载 类的初始化 运行时数据结构 JVM 指令集 异常处理 方法调用不同 JVM 的内部实现可以不同但对外表现需要符合规范要求。可以类比为Java虚拟机规范 建筑设计标准 JVM实现 按照标准建造出来的建筑八、JVM 不只能运行 Java这是理解 JVM 时非常重要的一点。很多人会认为JVM Java 专用运行环境实际上并不完全准确。JVM 真正识别的并不是.java文件而是.class 字节码文件只要一种编程语言最终能够生成符合 JVM 规范的字节码就可以运行在 JVM 上。例如Java Kotlin Scala Groovy都可以运行在 JVM 生态中。所以更加准确的关系应该是Java Kotlin Scala Groovy ↓ 编译 ↓ Class 字节码 ↓ JVM从这个角度看JVM 本质上是一个字节码运行平台。九、常见的 JVM 实现目前 JVM 存在多种实现其中比较常见的包括JVM主要特点常见应用HotSpot使用范围最广生态成熟Java 常规开发GraalVM支持 JIT、AOT 和多语言云原生、微服务Alibaba Dragonwell基于 OpenJDK 优化企业级高性能场景Eclipse OpenJ9强调低内存、高性能云计算、微服务其中开发者接触最多的通常是HotSpot十、HotSpot JVMHotSpot 是当前 Java 生态中使用非常广泛的一种 JVM 实现。很多开发者安装 OpenJDK 或 Oracle JDK 后默认使用的就是 HotSpot。查看当前 JVM 信息可以执行java-version例如可能看到OpenJDK 64-Bit Server VM其中Server VM通常就是 HotSpot 的 Server 模式。十一、HotSpot 名字是怎么来的HotSpot这个名字实际上与它的核心技术思想有关。HotSpot 可以理解成热点JVM 会在程序运行期间持续观察代码执行情况哪些方法执行次数最多 哪些循环运行最频繁 哪些代码属于性能关键路径当某些代码被判断为热点代码后JIT 编译器就可以对它们进行进一步优化。因此HotSpot ↓ 寻找热点代码 ↓ JIT 编译 ↓ 优化机器指令 ↓ 提高运行效率这也是现代 Java 能够获得较高运行性能的重要原因。十二、HotSpot 的发展HotSpot 的发展与 JDK 的演进密切相关。可以大致梳理为JDK 1.2 ↓ HotSpot 开始进入 JDK JDK 1.3 ↓ 逐渐成为主要 JVM 实现 JDK 6 ↓ JVM 性能进一步优化 JDK 7 ↓ G1 垃圾回收器出现 JDK 8 ↓ JVM 工具和内存管理进一步完善 JDK 9 ↓ G1 逐渐成为默认垃圾回收器 JDK 11 ↓ ZGC 等低延迟垃圾回收器不断发展 现代 JDK ↓ GraalVM、ZGC 等技术持续演进JVM 的发展方向一直围绕几个核心目标更高吞吐量 更低延迟 更少内存占用 更快启动速度 更强运行时优化能力十三、JDK、JRE、JVM 的关系初学 JVM 时还需要把三个容易混淆的概念区分开JDK JRE JVM可以简单理解为JDK ├── Java开发工具 │ ├── javac │ ├── javadoc │ ├── jdb │ └── ... │ └── Java运行相关能力 └── JVM三者关注点不同名称作用JVM负责执行 Java 字节码JRE提供 Java 程序运行所需环境JDK提供 Java 程序开发、编译、运行等能力对于 Java 开发者来说平时安装的通常是JDK而 JVM 是 JDK 中最核心的组成部分之一。十四、整体知识结构把前面的内容串联起来可以形成这样一条完整链路Java源代码 ↓ javac编译 ↓ Class字节码 ↓ JVM ├── 加载字节码 ├── 解释执行 ├── 管理内存 ├── 自动GC └── JIT编译优化 ↓ 机器指令 ↓ CPU执行Java 能够实现跨平台本质上依赖于统一的字节码格式 不同平台对应的 JVM 实现而 Java 能够兼顾开发效率与运行性能则与 JVM 提供的自动内存管理 垃圾回收 解释执行 即时编译 运行时优化密切相关。十五、核心知识点总结初识 JVM 阶段可以重点掌握下面几个结论。1. JVM 是什么JVM 全称 Java Virtual Machine本质是运行 Java 字节码的程序。2. Java 程序如何运行.java ↓ javac .class ↓ JVM 机器指令 ↓ CPU3. Java 为什么能够跨平台因为 Java 编译后生成统一的字节码不同操作系统通过各自对应的 JVM 执行相同字节码。4. JVM 有哪些核心功能主要包括解释和执行字节码 内存管理 垃圾回收 即时编译优化5. 什么是 JITJIT 是即时编译器。它可以将频繁执行的热点字节码编译成优化后的机器指令从而提升程序运行效率。6. JVM 是否只能运行 Java不是。JVM 真正执行的是符合规范的字节码因此 Kotlin、Scala、Groovy 等语言也可以运行在 JVM 上。7. 最常见的 JVM 是什么目前 Java 开发中最常见的 JVM 实现之一是HotSpot它拥有成熟的 JIT、垃圾回收和运行时优化体系。十六、面试常见问题Q1JVM 是什么JVM 是 Java Virtual Machine 的缩写本质上是一个运行 Java 字节码的程序。它负责字节码执行、内存管理、垃圾回收以及运行时优化等工作。Q2Java 为什么可以跨平台Java 源代码经过编译以后生成与操作系统无关的 Class 字节码不同操作系统提供对应的 JVM 实现由 JVM 将字节码转换成当前平台可以执行的机器指令因此实现跨平台。Q3JVM 的主要作用有哪些可以概括为① 运行 Java 字节码 ② 管理运行时内存 ③ 自动进行垃圾回收 ④ 通过 JIT 优化热点代码Q4JVM、JDK、JRE 有什么区别JVM 负责执行字节码JRE 主要提供 Java 程序运行所需的环境JDK 面向开发者在运行环境之外还提供编译、调试等开发工具。Q5Java 是解释型语言还是编译型语言不能简单归为其中一种。Java 源代码首先通过javac编译成字节码程序运行期间 JVM 又会结合解释器和 JIT 即时编译器执行代码。所以 Java 实际采用的是编译 解释执行 即时编译相结合的运行方式。十七、结语理解 JVM 的第一步并不是立即研究垃圾回收算法或者复杂的 JVM 参数而是先建立完整的运行模型Java代码为什么不能直接运行 Class文件是什么 为什么相同的Class文件可以运行在不同操作系统 JVM承担了哪些职责 解释器和JIT分别解决什么问题理解这些问题以后再继续学习字节码、类加载机制、运行时数据区、对象内存分配以及垃圾回收就会更加容易建立起完整的 JVM 知识体系。若有转载请标明出处https://blog.csdn.net/CharlesYuangc/article/details/164885060
返回列表