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

Java学习第六十部分——JVM

目录

一. 关键概述

二. 核心功能

三. 组成架构

1. 类加载子系统 (ClassLoader)

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

3. 执行引擎 (Execution Engine)

四. 类加载机制

五. 垃圾回收 (GC)

六. JIT 编译器 (Just-In-Time)

七. 调优参数示例

八. 常见问题与工具

九. 与 JDK/JRE 的关系

十. 调优与监控

十一. 常见实现

十二. 简单示例

十三. 总结归纳


一. 关键概述

       Java 虚拟机(JVM,Java Virtual Machine)是 Java 平台的核心组成部分,负责将编译后的字节码(`.class` 文件)解释或编译为机器码,并在不同操作系统上实现“一次编写,到处运行”(Write Once, Run Anywhere)的跨平台特性。

二. 核心功能

  • 跨平台执行:将字节码翻译成不同操作系统的本地机器指令。

  • 内存管理:自动分配/回收内存(堆、栈等),避免手动管理错误。

  • 垃圾回收 (GC):自动回收无用的对象内存。

  • 字节码执行:通过解释器或 JIT 编译器执行字节码。

三. 组成架构

1. 类加载子系统 (ClassLoader)
组件功能描述关键特性
Bootstrap ClassLoader加载 JAVA_HOME/lib 的核心类库(如 rt.jar由 C++ 实现,JVM 自身的一部分
Extension ClassLoader加载 JAVA_HOME/lib/ext 目录的扩展类库继承自 URLClassLoader,父加载器为 Bootstrap
Application ClassLoader加载用户类路径(classpath)的类默认线程上下文类加载器,父加载器为 Extension
双亲委派模型加载类时优先委派父类加载器处理避免核心类被篡改(如自定义 java.lang.String),确保安全性和类唯一性

2. 运行时数据区 (Runtime Data Areas)
内存区域存储内容特性
方法区 (Method Area)类元数据(类名、字段、方法)、常量池、静态变量JDK 8+ 由元空间 (Metaspace) 实现,使用本地内存,替代永久代(PermGen)
堆 (Heap)对象实例和数组垃圾回收主区域,分为:
- 新生代(Eden + Survivor From/To)
- 老年代
虚拟机栈 (JVM Stack)每个线程私有,存储栈帧(局部变量表、操作数栈、动态链接、方法出口)方法调用压栈,返回弹栈;可能抛出 StackOverflowError
本地方法栈服务于 Native 方法(如 JNI 调用的 C/C++ 代码)与虚拟机栈类似,但针对本地方法
程序计数器 (PC Register)记录当前线程执行的字节码指令地址唯一不会发生 OOM 的区域,线程私有

3. 执行引擎 (Execution Engine)
组件功能描述关键实现
解释器 (Interpreter)逐行解释字节码为机器码执行启动速度快,但运行时效率低
JIT 编译器将热点代码(高频方法/循环)编译为本地机器码HotSpot 使用分层编译:
- C1 编译器(客户端,快速优化)
- C2 编译器(服务端,深度优化)
垃圾回收器 (GC)自动回收无引用对象的内存主流算法与收集器
- 新生代:复制算法(Parallel Scavenge)
- 老年代:标记-清除/整理(CMS)
G1 GC(JDK9+ 默认):区域化分代 + 可预测停顿
ZGC(JDK11+):低延迟(<10ms)、TB 级

核心关系总结

  • 类加载 → 运行时数据区:

ClassLoader 加载的类元数据存储于方法区,对象实例分配在堆中。

  • 执行引擎 → 运行时数据区:

解释器/JIT 执行栈中方法的字节码;GC 管理堆内存的回收。

  • 线程私有区域:

每个线程独立拥有:虚拟机栈、本地方法栈、程序计数器。

四. 类加载机制

类加载分三个阶段:
1. **加载 (Loading)**  
   - 通过类加载器(`ClassLoader`)加载 `.class` 文件到内存。
   - 类加载器层级:
     - **Bootstrap ClassLoader**(加载核心库如 `rt.jar`)
     - **Extension ClassLoader**(加载扩展库)
     - **Application ClassLoader**(加载用户类路径)
     - **自定义 ClassLoader**(用户扩展)。
2. **链接 (Linking)**  
   - 验证字节码合法性 → 准备(为静态变量分配内存)→ 解析(符号引用转直接引用)。
3. **初始化 (Initialization)**  
   - 执行静态代码块和静态变量赋值(如 `static int x = 10;`)。

五. 垃圾回收 (GC)

- **回收对象**:无引用指向的对象(如超出作用域的局部变量)。
- **GC 算法**:
  - **分代收集**:堆分为 **新生代 (Young)** 和 **老年代 (Old)**。
    - 新生代:使用 **复制算法**(Eden + Survivor 区)。
    - 老年代:使用 **标记-清除** 或 **标记-整理** 算法。
  - **垃圾收集器**:
    - **Serial GC**:单线程,适合小应用。
    - **Parallel GC**(默认):多线程,吞吐量优先。
    - **CMS** / **G1 GC**:低延迟,减少 STW(Stop-The-World)时间。
    - **ZGC** / **Shenandoah**(JDK 15+):超低延迟(<10ms)。

六. JIT 编译器 (Just-In-Time)

- **热点代码优化**:频繁执行的字节码会被编译成本地机器码(如循环、高频方法)。
- **解释器 vs JIT**:解释器逐行执行字节码(启动快);JIT 编译后执行(运行快)。

七. 调优参数示例

# 堆内存设置
-Xms512m    # 初始堆大小(默认物理内存 1/64)
-Xmx1024m   # 最大堆大小(默认物理内存 1/4)
-XX:NewRatio=2  # 老年代:新生代 = 2:1
-XX:SurvivorRatio=8  # Eden:Survivor = 8:1

# 垃圾回收器选择
-XX:+UseG1GC        # 启用 G1 收集器
-XX:+UseConcMarkSweepGC  # 启用 CMS 收集器

# 元空间设置(JDK 8+)
-XX:MetaspaceSize=128m  
-XX:MaxMetaspaceSize=256m

八. 常见问题与工具

- **内存泄漏**:对象被意外保留引用(如静态集合类持续增长)。
- **OOM (OutOfMemoryError)**:堆/元空间不足。
- **诊断工具**:
  - **jconsole** / **VisualVM**:图形化监控堆、线程、类加载。
  - **jstack**:分析线程堆栈(死锁检测)。
  - **jmap**:导出堆内存快照(配合 **MAT** 工具分析内存泄漏)。
  - **jstat**:监控 GC 状态(`jstat -gcutil <pid> 1000`)。

九. 与 JDK/JRE 的关系

- **JDK (Java Development Kit)**:开发工具包(含 JRE + 编译器 `javac`)。
- **JRE (Java Runtime Environment)**:运行环境(含 JVM + 基础库)。
- **JVM**:执行引擎,是 JRE 的子集。

十. 调优与监控

- **常用参数**:
  - 堆大小:`-Xms`(初始堆)、`-Xmx`(最大堆)。
  - 新生代比例:`-XX:NewRatio`。
  - GC 日志:`-Xlog:gc*`(JDK 9+)。
  - 元空间:`-XX:MaxMetaspaceSize`。
- **监控工具**:
  - **JVisualVM**:可视化监控线程、堆、GC。
  - **JConsole**:实时查看内存、线程、类加载。
  - **jstack**:查看线程堆栈(定位死锁)。
  - **jmap**:生成堆转储(`jmap -dump` 分析内存泄漏)。

十一. 常见实现

- **HotSpot**(Oracle/OpenJDK 默认):支持 JIT 和多种 GC。
- **OpenJ9**(IBM):低内存占用,适合云原生。
- **GraalVM**:多语言支持(Java/Python/JS),原生镜像(AOT 编译)。

十二. 简单示例

// 内存泄漏示例:静态集合持有对象引用
public class MemoryLeak {private static final List<Object> list = new ArrayList<>();public void addData() {while (true) {list.add(new byte[1024 * 1024]); // 持续占用内存}}
}

排查步骤:
1. 使用 `jmap -dump:format=b,file=heap.hprof <pid>` 生成堆转储。
2. 通过 MAT 或 VisualVM 分析泄漏路径(如 `list` 持续增长)。

十三. 总结归纳

JVM 是 Java 生态的基石,理解其内存模型、类加载、GC 机制是优化性能的关键。掌握 JVM 调优和诊断工具,能有效解决内存溢出、高延迟等问题。JVM 通过抽象操作系统差异、自动化内存管理和高效的执行引擎,成为 Java 高性能和跨平台能力的基石。理解其原理和调优技巧,是 Java 开发者进阶的必经之路。

http://www.dtcms.com/a/288660.html

相关文章:

  • An End-to-End Attention-Based Approach for Learning on Graphs NC 2025
  • 04 51单片机之数码管显示
  • Shell脚本-uniq工具
  • 两个路由器通过不同的网段互联
  • 从TPACK到TPACK - AI:人工智能时代教师知识框架的重构与验证
  • EPLAN 电气制图(十): 继电器控制回路绘制(下)放料、放灰
  • 基于单片机的IC卡门禁系统设计
  • 最大子数组和问题-详解Kadane算法
  • 每日一题7.20
  • OSS文件上传(一):简单上传
  • feignClient 调用详细流程
  • Valgrind Memcheck 全解析教程:6个程序说明基础内存错误
  • 判断一个数是否为质数方法
  • VSCode使用Jupyter完整指南配置机器学习环境
  • c#:TCP服务端管理类
  • 正点原子stm32F407学习笔记10——输入捕获实验
  • 2025 年科技革命时刻表:四大关键节点将如何重塑未来?
  • 内网后渗透攻击过程(实验环境)--3、横向攻击
  • SQL 调优第一步:EXPLAIN 关键字全解析
  • 【已解决】GitHub SSH 连接失败解决方案:Permission Denied (publickey) 错误修复指南
  • [Linux]进程 / PID
  • 30天打牢数模基础-决策树讲解
  • Linux入门篇学习——NFS 服务器的搭建和使用和开发板固件烧录
  • Spring Boot 第一天知识汇总
  • 【Java项目安全基石】登录认证实战:Session/Token/JWT用户校验机制深度解析
  • 相似度计算
  • 「Java案例」利用方法求反素数
  • Facebook 开源多季节性时间序列数据预测工具:Prophet 饱和预测 Saturating Forecasts
  • dynamic_cast的实现原理
  • Beamer-LaTeX学习(教程批注版)【6】