代码咖啡因的个人博客 代码咖啡因的个人博客

记录精彩的程序人生

目录
JVM 结构概述
/  

JVM 结构概述

JVM 结构概述

JVM 的核心结构可以分为以下几个部分:

  1. 类加载子系统(Class Loader Subsystem)
  2. 运行时数据区(Runtime Data Areas)
  3. 执行引擎(Execution Engine)
  4. 本地方法接口(Native Method Interface)
  5. 本地方法库(Native Libraries)

下面我们分别从这些部分来对比 JDK 8 和 JDK 17 的 JVM 结构。


1. 类加载子系统(Class Loader Subsystem)

类加载子系统负责加载 Java 类文件(.class 文件)到 JVM 中。

JDK 8 和 JDK 17 的类加载机制

  • 类加载器层次结构
    • Bootstrap ClassLoader:加载核心 Java 类(如 java.lang.*)。
    • Extension ClassLoader:加载扩展类(jre/lib/ext 目录下的类)。
    • Application ClassLoader:加载应用程序类路径(Classpath)下的类。
    • Custom ClassLoader:用户自定义的类加载器。
  • 双亲委派模型
    • 类加载器在加载类时,首先委托给父类加载器,只有在父类加载器无法加载时,才自己加载。
    • JDK 8 和 JDK 17 都遵循双亲委派模型。
  • 变化
    • JDK 9 引入了模块化系统(Jigsaw[音:急个啥]),类加载机制有所调整,但 JDK 17 仍然兼容 JDK 8 的类加载机制。

2. 运行时数据区(Runtime Data Areas)

运行时数据区是 JVM 内存管理的核心部分,主要包括以下几个区域:

JDK 8 的运行时数据区

  1. 方法区(Method Area)
    • 存储类信息、常量、静态变量等。
    • 在 JDK 8 中,方法区的实现是 永久代(PermGen)
  2. 堆(Heap)
    • 存储对象实例和数组。
    • 分为年轻代(Young Generation)和老年代(Old Generation)。
    • 年轻代进一步分为 Eden 区、Survivor 区(From 和 To)。
  3. 栈(Stack)
    • 每个线程私有的栈,存储局部变量和方法调用。
    • 包括局部变量表、操作数栈、动态链接、方法返回地址等。
  4. 程序计数器(Program Counter Register)
    • 记录当前线程执行的字节码指令地址。
  5. 本地方法栈(Native Method Stack)
    • 用于执行本地方法(Native Methods)。

JDK 17 的运行时数据区

  1. 元空间(Metaspace)
    • 取代了 JDK 8 中的永久代(PermGen)。
    • 存储类信息、常量、静态变量等。
    • 元空间使用本地内存(Native Memory),不再受 JVM 堆内存限制。
  2. 堆(Heap)
    • 与 JDK 8 类似,分为年轻代和老年代。
    • 支持更大的堆内存(如 ZGC 和 Shenandoah GC 支持 TB 级别的堆)。
  3. 栈(Stack)
    • 与 JDK 8 相同。
  4. 程序计数器(Program Counter Register)
    • 与 JDK 8 相同。
  5. 本地方法栈(Native Method Stack)
    • 与 JDK 8 相同。

变化

  • 永久代被元空间取代
    • JDK 8 的永久代容易导致OutOfMemoryError: PermGen space 错误。
    • JDK 17 使用元空间,动态调整内存大小,避免了永久代的限制。

3. 执行引擎(Execution Engine)

执行引擎负责执行字节码指令。

JDK 8 和 JDK 17 的执行引擎

  • 解释器(Interpreter)
    • 逐行解释执行字节码。
  • 即时编译器(JIT Compiler)
    • 将热点代码(HotSpot)编译为本地机器码,提高执行效率。
    • JDK 8 和 JDK 17 都使用****C1(Client Compiler)C2(Server Compiler)
  • 垃圾回收器(Garbage Collector)
    • JDK 8 默认使用 Parallel GC。
    • JDK 17 默认使用 G1 GC,并引入了 ZGC 和 Shenandoah GC。

变化

  • JDK 17 对 JIT 编译器进行了优化,提升了编译效率。
  • JDK 17 引入了新的垃圾回收器(如 ZGC 和 Shenandoah GC),支持更低延迟和更大堆内存。

4. 本地方法接口(Native Method Interface)

  • 提供 Java 代码调用本地方法(如 C/C++ 代码)的能力。
  • JDK 8 和 JDK 17 的本地方法接口基本一致。

5. 本地方法库(Native Libraries)

  • 包含 JVM 所需的本地库(如线程、网络、文件系统等)。
  • JDK 17 对本地方法库进行了优化,提升了性能和兼容性。

JDK 8 和 JDK 17 的 JVM 结构对比总结

组件JDK 8JDK 17
类加载子系统双亲委派模型双亲委派模型,支持模块化系统
方法区永久代(PermGen)元空间(Metaspace)
堆内存年轻代 + 老年代年轻代 + 老年代,支持更大堆内存
垃圾回收器默认 Parallel GC默认 G1 GC,支持 ZGC、Shenandoah
执行引擎C1 和 C2 编译器优化后的 C1 和 C2 编译器
本地方法接口支持本地方法调用支持本地方法调用
本地方法库基础本地库优化后的本地库

总结

  • JDK 8 的 JVM 结构以永久代和 Parallel GC 为特点,适合传统的 Java 应用。
  • JDK 17 的 JVM 结构引入了元空间、G1 GC、ZGC 等新技术,更适合现代应用(如低延迟、大内存场景)。
  • JDK 17 在性能、内存管理和垃圾回收方面有显著改进,推荐在新项目中使用。