当前位置: 首页 > web >正文

JVM内存模型

目录

1、什么是JVM?

2、为什么要学习JVM?

(1)​深入理解Java程序的运行机制​

(2)优化程序性能​

(3)​排查线上问题​

(4)​编写高效代码​

(5)​跨平台与语言无关性​

(6)​面试与职业发展​

3、JVM的体系结构

​3.1 类加载子系统(Class Loader SubSystem)​​

​​(1) 加载(Loading)​​

​​(2) 链接(Linking)​​

​​(3) 初始化(Initialization)​​

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

​​(1) 线程私有区域(每个线程独立)​​

​​(2) 线程共享区域(所有线程共用--->非线程安全的)​​

​3.3 执行引擎(Execution Engine)​​

​​(1) 解释器(Interpreter)​​

​​(2) JIT编译器(Just-In-Time Compiler)​​

​​(3) 垃圾回收(Garbage Collection)​​

​​(4) 本地方法接口(JNI, Java Native Interface)​​

​3.4 数据流向总结​

4、在Java 8版本之后的更新

4.​1 类加载子系统的改进​

4.​2 运行时数据区的重大变化​

​​(1) 方法区 → 元空间(Metaspace)​​

​​(2) 堆内存与垃圾回收器​

​​(3) 线程栈优化​

4.​3 执行引擎的增强​

​4.4 工具链与监控的演进​

4.5 ​总结​

5、新特性探索(Java 8+)

模块一:Java 8~Java 11

5.​1 模块化(Java 9+)​​

5.​2 元空间(Metaspace)取代永久代​

5.3 GC 行为变化(CMS 移除)​​

模块二:Java 11~Java 17

​​5.4 低延迟 GC:ZGC 与 Shenandoah​

​5.5 GraalVM 原生镜像(AOT 编译)​​

​5.6 虚拟线程(Loom 项目,Java 19 正式)​​

​模块三:新特性详解​

​5.7 元空间调优​

​5.8 G1/ZGC 原理​

​5.9 JFR(Java Flight Recorder)诊断​


1、什么是JVM?

  • Java Virtual Machine(Java虚拟机),用来保证Java语言跨平台。
  • Java虚拟机可以看做是一台抽象的计算机,如同真实的计算机那样,它有自己的指令集以及各种运行时内存区域。

        JVM模拟了真实计算机的架构,拥有独立的指令集(如字节码指令)和内存管理机制(如堆、栈、方法区等)。这种设计使得Java程序无需直接操作物理硬件,而是通过JVM的统一接口运行,从而实现跨平台性。例如,javac编译生成的字节码(.class文件)是JVM的“指令集”,而堆内存用于存储对象实例,栈内存用于方法调用。

  • Java虚拟机与Java语言并没有必然的联系,它只与特定的二进制文件格式(class文件格式)所关联。

        JVM的核心规范是处理符合class文件格式的二进制文件,而非特定语言。这意味着任何能编译成合规字节码的语言(如Kotlin、Scala)均可运行在JVM上。例如,Groovy编写的代码编译后也能被JVM执行,体现了JVM的“语言无关性”。

  • Java虚拟机就是一个字节码翻译器,它将字节码文件翻译成各个系统对应的机器码,确保字节码文件能在各个系统正确运行。

        JVM通过解释或即时编译(JIT)将字节码转换为目标系统的原生机器码。例如,在Windows和Linux上,同一份.class文件会被JVM分别翻译为x86或ARM指令,确保程序在不同OS上行为一致。这种“一次编译,到处运行”的特性依赖JVM对各平台的适配。

2、为什么要学习JVM?

学习 ​JVM(Java虚拟机)​​ 是Java开发者进阶的必经之路,主要原因包括以下几个方面:

(1)​深入理解Java程序的运行机制

  • Java程序不是直接运行在操作系统上,而是通过JVM执行字节码。
  • 了解JVM如何加载类、管理内存、执行字节码等,能帮助你写出更高效、稳定的代码。
  • 例如:理解ClassLoader机制可以避免类加载冲突,优化启动性能。

(2)优化程序性能

  • JVM的内存管理(堆、栈、方法区)、垃圾回收(GC)机制直接影响程序性能。
  • 掌握JVM调优(如调整堆大小、选择合适的GC算法)可以显著提升高并发、大数据量场景下的应用性能。
  • 例如:-Xms-Xmx参数调整堆内存,避免频繁GC导致的卡顿。

(3)​排查线上问题

  • 线上环境可能出现OOM(内存溢出)CPU飙升线程死锁等问题,掌握JVM工具(如jstackjmapVisualVM)看懂GC日志就能够快速定位问题。
  • 例如:用jstack分析线程堆栈,找出死锁或阻塞的代码。

(4)​编写高效代码

  • 了解JVM内存模型(如逃逸分析栈上分配)可以优化对象创建方式,减少GC压力。
  • 例如:Stringintern()方法可以复用字符串常量池,减少内存占用。

(5)​跨平台与语言无关性

  • JVM不仅支持Java,还支持Kotlin、Scala、Groovy等JVM语言,理解JVM有助于学习这些语言的底层机制。
  • 例如:Kotlin的协程底层依赖JVM的线程模型。

(6)​面试与职业发展

  • JVM是Java面试的核心考点之一(如GC、类加载、内存模型),掌握JVM能提升竞争力。
  • 高级开发、架构师等岗位通常要求深入理解JVM调优和底层原理。

3、JVM的体系结构

如下图所示,这是一个JVM的体系结构图(基于Java8的环境):

​这张JVM体系结构图清晰地展示了Java虚拟机的主要组成部分及其运行流程,主要包括 ​类加载子系统(Class Loader SubSystem)​运行时数据区(Runtime Data Areas)​​ 和 ​执行引擎(Execution Engine)​​ 三大部分。下面我们逐一解析每个模块的功能和流程。


​3.1 类加载子系统(Class Loader SubSystem)​

负责运行时首次引用类文件时加载.class文件到内存,并转换为JVM可识别的数据结构。类加载过程分为 ​加载(Loading)→ 链接(Linking)→ 初始化(Initialization)​​ 三个阶段:

​(1) 加载(Loading)​
  • 任务​:查找并加载.class文件(二进制字节码)到内存。
  • 类加载器(Class Loader)​​:
    • Bootstrap Class Loader(启动类加载器)​​:加载JRE/lib下的核心类库(如java.lang.*)。
    • Extension Class Loader(扩展类加载器)​​:加载JRE/lib/ext下的扩展类。
    • Application Class Loader(应用程序类加载器)​​:加载用户程序的类(classpath下的类)。
​(2) 链接(Linking)​
  • 验证(Verify)​​:检查字节码是否符合JVM规范(如魔数0xCAFEBABE),如果验证失败将会收到验证错误。
  • 准备(Prepare)​​:为 ​静态变量​ 分配内存并设置默认值(如int初始化为0)。
  • 解析(Resolve)​​:将符号引用(如类名、方法名)转换为直接引用(内存地址)。
​(3) 初始化(Initialization)​
  • 执行<clinit>()方法(静态变量赋值、执行静态代码块)。
  • 例如:static int a = 100; 在此阶段赋值。

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

JVM运行时的内存模型,分为 ​线程私有​ 和 ​线程共享​ 区域:

​(1) 线程私有区域(每个线程独立)​
  • 程序计数器(PC Register)​
    • 记录当前线程执行的字节码指令地址(线程切换后恢复执行位置)。
    • PS:每一个线程都有自己的​程序计数器。
  • 虚拟机栈(Stack Area)​
    • 存储 ​栈帧(Stack Frame)​,每个方法调用对应生成一个栈帧,所有的局部变量都会在栈内存创建,其中栈帧包含:
      • 局部变量表(LVA)​​:存放方法参数和局部变量。
      • 操作数栈(Operand Stack)​​:用于计算中间结果(如i++操作)。
      • 动态链接(Dynamic Linking)​​:指向运行时常量池的方法引用。
      • 方法返回地址​:方法执行完毕后返回的位置。
  • 本地方法栈(Native Method Stack)​
    • native方法(如C/C++代码)提供运行环境。
    • PS:对应的,每个线程都会创建自己的本地方法栈
​(2) 线程共享区域(所有线程共用--->非线程安全的)​
  • 堆(Heap Area)​
    • 存储 ​所有对象实例和数组,是垃圾回收(GC)的主要区域。
    • 分为 ​新生代(Young Gen)​​ 和 ​老年代(Old Gen)​
  • 方法区(Method Area)​
    • 存储 ​类信息、常量、静态变量、JIT编译后的代码​(JDK 8后由 ​元空间Metaspace​ 实现)。
    • PS:每个Java虚拟机都只有一个方法区,所以他是公共的。

3.3 执行引擎(Execution Engine)​

负责执行字节码,核心组件包括:

​(1) 解释器(Interpreter)​
  • 逐行解释执行字节码(启动快,但执行效率低)。
  • 当一个方法被调用多次的时候,他还是会逐一解释,所以JIT编译器应运而生。
​(2) JIT编译器(Just-In-Time Compiler)​
  • 热点代码优化​:将频繁执行的字节码(比如上文提到的多次调用一个方法的重复代码)编译为本地机器码(本地代码会直接用于系统调用,从而提升性能)。
  • 工作流程​:
    • Profiler(分析器)​​:识别热点代码(如循环、高频调用方法)。
    • Code Optimizer(代码优化器)​​:优化字节码(如内联、逃逸分析)。
    • Target Code Generator(目标代码生成器)​​:生成机器码。
​(3) 垃圾回收(Garbage Collection)​
  • 自动回收堆内存中的无用对象(如引用计数、可达性分析算法)。
  • 我们可以通过调用System.gc()方法触发垃圾回收器,但是不能保证执行。

​(4) 本地方法接口(JNI, Java Native Interface)​
  • 调用本地方法(如System.currentTimeMillis()底层用C实现)。

​3.4 数据流向总结

  1. 类加载​:.class文件 → 类加载子系统 → 方法区(存储类信息)。
  2. 运行阶段​:
    • 线程栈执行方法 → 操作数栈计算 → 堆内存创建对象。
    • JIT优化热点代码 → 生成机器码加速执行。
  3. 垃圾回收​:堆内存中的无用对象被GC清理。

4、在Java 8版本之后的更新

4.​1 类加载子系统的改进

模块Java 8Java 11/17
类加载器Bootstrap/Extension/Application模块化系统(Java 9+)​​:引入 Layer 分层加载机制,支持动态模块依赖。
加载过程固定路径(JRE/lib, ext, classpath)模块路径(module-path)​​ 替代 classpath,增强隔离性。
元数据存储永久代(PermGen)存储类元数据元空间(Metaspace)​​:类元数据移至本地内存,默认无上限(-XX:MaxMetaspaceSize 可限制)。

影响​:

  • 永久代 OOM 问题消失,但需监控元空间占用(如滥用动态类生成仍会触发 Metaspace OOM)。
  • 模块化减少类冲突(如 javax vs jakarta),但需适应新打包方式(jlink 生成定制化运行时)。

4.​2 运行时数据区的重大变化

​(1) 方法区 → 元空间(Metaspace)​
- Java 8: Method Area (PermGen)- 固定大小(`-XX:PermSize=64m`),易触发 `OutOfMemoryError: PermGen space`。- 存储:类元数据、运行时常量池、静态变量。+ Java 17: Metaspace- 本地内存管理,默认自动扩展(受限于物理内存)。- 存储:仅类元数据(静态变量移至堆中)。- 调优:`-XX:MaxMetaspaceSize=256m` 限制上限。
​(2) 堆内存与垃圾回收器
特性Java 8Java 11/17
默认 GCParallel GC(吞吐优先)G1 GC​(平衡吞吐/延迟)
低延迟 GCZGC​(亚毫秒级停顿,Java 11+)
Shenandoah​(低停顿,Java 12+)
堆分区固定新生代/老年代比例G1 的 ​Region-Based​ 动态分区

影响​:

  • ZGC/Shenandoah 适用于微服务、实时系统(如支付交易),但需显式启用:
    java -XX:+UseZGC -jar app.jar
  • G1 的默认化减少调优负担,但需理解 ​Region​ 和 ​Mixed GC​ 机制。
​(3) 线程栈优化
  • Java 15+ 虚拟线程(预览)​​:
    • 轻量级线程(JEP 425),减少栈内存占用和上下文切换开销。
    • 替代传统 Thread 模型,适用于高并发(如 10W+ 连接)。
    Thread.startVirtualThread(() -> {...}); // Java 19 正式发布

4.​3 执行引擎的增强

组件Java 8Java 11/17
JIT 编译器C1/C2 分层编译Graal JIT​(Java 10+ 可选)
AOT 编译不支持GraalVM AOT​(生成原生镜像,Java 17+)
本地方法传统 JNIProject Panama​(预览,简化 FFI 调用)

影响​:

  • Graal JIT​:更激进的优化(如逃逸分析),但可能增加编译时间。
  • AOT 编译​:提升启动速度(如 Spring Native),但牺牲动态性(反射需配置)。
    native-image -jar app.jar  # 生成原生可执行文件

​4.4 工具链与监控的演进

工具Java 8Java 11/17
监控工具jstat、jmap、VisualVMJDK Mission Control (JMC)​
Java Flight Recorder (JFR)​
命令行jcmd 功能有限增强版 jcmd(支持 Metaspace/ZGC 诊断):
jcmd <pid> VM.metaspace
日志GC 日志需手动解析统一日志(-Xlog)​​:
-Xlog:gc*=debug:file=gc.log

示例(Java 17 ZGC 日志分析)​​:

java -XX:+UseZGC -Xlog:gc*=info:file=zgc.log -jar app.jar

4.5 ​总结

Java 11/17 的 JVM 在 ​内存模型​(元空间)、垃圾回收​(ZGC)、执行效率​(Graal/AOT)和 ​可观测性​(JFR)上大幅改进,但核心架构(类加载、堆栈模型)仍与 Java 8 一脉相承。


5、新特性探索(Java 8+)

模块一:Java 8~Java 11

5.​1 模块化(Java 9+)​
  • 问题背景​:
    图中 Class Loader SubSystemBootstrap/Extension/Application 三层加载器在 Java 8 中依赖 classpath,易引发 ​JAR 地狱​(如版本冲突)。
  • Java 11 解决方案​:
    • 模块化系统(JPMS)​​:
      • 类加载改为 ​模块路径(module-path)​​ 替代 classpath,每个模块声明依赖(module-info.java)。
      • 新增 Layer 分层加载机制,支持动态模块化部署。
    • 影响​:
      • 需重构大型项目为模块(如拆分 com.example 为独立模块)。
      • 工具链变化:jlink 生成定制化运行时,剔除未用模块减小体积。
        jlink --add-modules java.base --output minimal-jre
5.​2 元空间(Metaspace)取代永久代
  • ​与上图对比​:
    原图的 Method Area(永久代)在 Java 8 中通过 -XX:PermSize 固定大小,易触发 OutOfMemoryError: PermGen space
  • Java 11 变化​:
    • 元空间(Metaspace)特性​:
      • 类元数据移至 ​本地内存,默认无上限(受限于物理内存)。
      • 字符串常量池、静态变量移至 ​堆内存
    • 调优参数​:
      -XX:MaxMetaspaceSize=256m  # 限制上限
      -XX:MetaspaceSize=64m      # 初始大小
    • 监控命令​:
      jcmd <pid> VM.metaspace    # 查看元空间使用详情
5.3 GC 行为变化(CMS 移除)​
  • 图中对比​:
    原图 Execution EngineGarbage Collection 未明确收集器类型,Java 8 默认 Parallel GC,CMS 为老年代低停顿选项。
  • Java 11 更新​:
    • CMS 移除​:改用 ​G1(Garbage-First)​​ 作为默认收集器。
    • G1 核心改进​:
      • Region-Based 堆分区​:取代固定新生代/老年代比例,动态调整 Region 用途。
      • Mixed GC 模式​:同时回收新生代和老年代 Region。
    • 调优示例​:
      -XX:+UseG1GC -XX:MaxGCPauseMillis=200  # 目标停顿时间

模块二:Java 11~Java 17

​​5.4 低延迟 GC:ZGC 与 Shenandoah
  • ZGC(Java 11+)​​:
    • 目标​:亚毫秒级停顿(<1ms),适合实时交易系统。
    • 原理​:
      • 染色指针​(Colored Pointers):在指针中存储元数据,加速标记。
      • 并发压缩​:无需停顿线程整理内存。
    • 启用命令​:
      -XX:+UseZGC -Xmx16g -Xlog:gc*=info:file=zgc.log
  • Shenandoah(Java 12+)​​:
    • 类似 ZGC,但通过 ​Brooks 指针实现并发压缩,适用于大堆(>32GB)。
​5.5 GraalVM 原生镜像(AOT 编译)​
  • 图中对比​:
    原图 Execution EngineJIT Compiler(C1/C2)在 Java 17 中可替换为 ​Graal JIT​ 或 ​AOT 编译
  • 原生镜像特性​:
    • 将 Java 程序编译为独立可执行文件(无需 JVM),启动速度提升 10x。
    • 限制​:反射、动态类加载需提前配置(reflect-config.json)。
    • 示例​:
      native-image -jar app.jar --no-fallback
​5.6 虚拟线程(Loom 项目,Java 19 正式)​
  • 背景​:
    原图的 Stack Area 中每个线程固定占用 ~1MB 栈内存,高并发时成本太高了。
  • 虚拟线程​:
    • 轻量级线程(协程),由 JVM 调度,复用 OS 线程。
    • 支持百万级并发(传统线程仅千级)。
    • 示例​:
      Thread.startVirtualThread(() -> System.out.println("Virtual Thread"));

模块三:新特性详解

​5.7 元空间调优
  • 监控工具​:
    • JMC/JFR​:实时监控 Metaspace 使用率与 GC 事件。
    • Arthas​:诊断类加载泄漏(如动态生成类未卸载)。
  • 常见问题​:
    • Metaspace OOM​:因滥用 CGLIB/ASM 动态生成类,需限制大小或优化代码。
​5.8 G1/ZGC 原理
收集器G1(Java 8+)​ZGC(Java 11+)​
目标平衡吞吐与停顿(~200ms)亚毫秒级停顿(<1ms)
堆布局固定大小 Region动态 Region(无分代)
标记并发标记 + SATB 算法并发染色指针
压缩并行压缩(Mixed GC 阶段停顿)并发压缩(无停顿)
​5.9 JFR(Java Flight Recorder)诊断
  • 启用命令​:
    -XX:StartFlightRecording=delay=5s,duration=60s,name=myrecording,filename=recording.jfr
  • 关键事件​:
    • jdk.GCPhase:分析 GC 停顿时间。
    • jdk.MetaspaceAllocationFailure:定位元空间问题。
  • 工具​:
    • JMC​ 可视化分析 .jfr 文件。

通过对比原图与新版特性,可以清晰看到 JVM 从 ​固定内存模型​ 向 ​动态化、低延迟、云原生​ 的演进方向。

http://www.xdnf.cn/news/6298.html

相关文章:

  • 前端面试题:vue3 为什么不需要时间分片?
  • Linux程序设计--期末复习
  • 企业网络新选择:软件定义架构下的MPLS
  • 【Docker】Windows10环境下安装DockerDesktop
  • TCP 三次握手建立连接详解
  • C2S-Scale:Cell2Sentence v2
  • 在星河社区学习PARL使用强化学习来训练AI
  • C#高级编程:IO和序列化
  • linux内核主要由哪五个模块构成?
  • ultralytics 中的 RT-DETR 之 模型结构解析
  • 【python机器学习】Day 25 异常处理
  • 吴恩达机器学习笔记:多变量梯度下降
  • Permission Denied Error on Port 6277 When Starting MCP
  • 彻底解决QT5 中文编译不过问题
  • HCIP-Datacom Core Technology V1.0_1认识网络设备
  • 【unity游戏开发——编辑器扩展】EditorWindow自定义unity窗口拓展
  • AI-02a5a6.神经网络-与学习相关的技巧-批量归一化
  • Spring Boot拦截器详解:原理、实现与应用场景
  • centos7忘记root密码后使用单用户模式重置
  • 算法备案如何判断自己的产品是否具备舆论属性
  • LeetCode100.5 盛最多水的容器
  • Linux系统之----基础IO
  • 亚马逊电商广告革命:当AI推荐沦为红海陷阱,中国卖家如何破局?
  • AI预测3D新模型百十个定位预测+胆码预测+去和尾2025年5月14日第77弹
  • 最短路与拓扑(2)
  • vim启动的时候,执行gg
  • 现场维护三重四极杆质谱系统和四极杆清洗方法,确保所有目标化合物的可靠性检测
  • 牛顿均差知识
  • 写作--简单句基础练习
  • AI时代的弯道超车之第九章:AI如何改变传统教育模式