说说JVM的底层原理(JAVA是如何运行的)?


JVM 底层原理深度解析

Java 虚拟机(JVM)是 Java 程序运行的核心环境,其设计融合了内存管理、类加载、垃圾回收和高效执行等复杂机制。以下从底层视角详细解析其核心模块,并结合实际场景说明其工作原理。


一、类加载机制

1. 类加载的触发与过程

类加载是 JVM 动态性的基石,其触发条件包括首次使用类(如 new、反射调用等)或继承父类时。整个过程分为三个阶段:

  1. 加载(Loading)

    • 功能:将 .class 字节码文件加载到内存,生成 Class 对象。
    • 实现细节
      • 类加载器(ClassLoader)通过全限定名查找 .class 文件。
      • 支持从文件系统、JAR 包、网络等来源加载。
    • 示例
      // 用户调用 new UserService() 时,触发 UserService.class 的加载
      UserService user = new UserService();
      
  2. 链接(Linking)

    • 验证(Verification):确保字节码符合 JVM 规范,防止恶意代码注入。
      • 文件格式验证:检查魔数(0xCAFEBABE)、版本号等。
      • 元数据验证:检查继承关系(如是否实现抽象方法)、字段类型等。
    • 准备(Preparation):为静态变量分配内存并赋零值。
      • 示例public static int count; 在准备阶段初始化为 0
      • 常量特殊处理public static final int MAX = 100; 直接赋值为 100
    • 解析(Resolution):将符号引用(如类名、方法名)转换为直接引用(内存地址)。
      • 示例:将 System.out.println 解析为实际的方法地址。
  3. 初始化(Initialization)

    • 执行 <clinit> 方法,合并所有静态代码块和静态变量赋值,按代码顺序执行。
    • 父类优先原则:若父类未初始化,先触发父类的初始化。
    • 示例
      static {
          System.out.println("静态代码块执行");
      }
      
2. 双亲委派模型
  • 核心思想:类加载请求优先委派父加载器处理,避免重复加载和核心类篡改。
  • 加载器层级
    • Bootstrap ClassLoader:加载 jre/lib 下的核心类(如 java.lang.*)。
    • Extension ClassLoader:加载 jre/lib/ext 下的扩展类。
    • Application ClassLoader:加载用户类路径(-classpath)的类。
    • 自定义 ClassLoader:用户扩展的加载器(如 Tomcat 的 WebappClassLoader)。
  • 破坏场景
    • SPI 机制:JDBC 驱动加载需使用线程上下文类加载器(ThreadContextClassLoader)。
    • 热部署:通过自定义类加载器实现类的动态替换。

二、内存管理

1. 内存区域划分

JVM 内存划分为多个区域,各司其职:

  1. 堆(Heap)

    • 功能:存储对象实例和数组,所有线程共享。
    • 分区
      • 新生代(Young Generation):新对象分配区,分 Eden、Survivor0、Survivor1。
      • 老年代(Old Generation):长期存活对象区。
    • 内存分配策略
      • 指针碰撞(堆内存规整时)或 空闲列表(内存碎片化时)。
      • TLAB(Thread Local Allocation Buffer):为每个线程预分配内存,避免竞争。
    • 示例
      Object obj = new Object(); // 对象分配在堆中
      
  2. 虚拟机栈(JVM Stack)

    • 功能:存储方法调用的栈帧(局部变量表、操作数栈、动态链接、方法出口)。
    • 栈帧结构
      • 局部变量表:存放方法参数和局部变量。
      • 操作数栈:执行字节码指令的工作区。
      • 动态链接:指向方法区的方法引用。
    • 示例
      public void calculate() {
          int a = 1;  // 存入局部变量表
          int b = 2;
          int c = a + b; // 操作数栈执行加法
      }
      
  3. 方法区(Method Area)

    • 功能:存储类信息、常量、静态变量。
    • 实现演变
      • JDK 7 及之前:永久代(PermGen),固定大小易导致 OutOfMemoryError
      • JDK 8+:元空间(Metaspace),使用本地内存,动态扩展。
    • 示例
      public static final String NAME = "JVM"; // 常量池存储在方法区
      
  4. 程序计数器(Program Counter Register)

    • 功能:记录当前线程执行的字节码指令地址(线程私有)。
    • 意义:线程切换后能恢复到正确执行位置。
2. 对象生命周期
  1. 创建

    • 类加载检查分配内存初始化零值设置对象头执行构造方法
    • 对象头结构
      • Mark Word:存储哈希码、GC 分代年龄、锁状态等。
      • 类型指针:指向类元数据(方法区中的 Class 对象)。
    • 示例
      User user = new User(); // 触发对象创建流程
      
  2. 内存回收

    • 对象不再被引用时,由垃圾回收器回收内存。

三、垃圾回收(GC)

1. 对象存活判定
  • 引用计数法:循环引用问题(Java 未采用)。
  • 可达性分析(主流):从 GC Roots 出发,标记不可达对象为垃圾。
    • GC Roots 包括
      • 虚拟机栈中引用的对象(局部变量)。
      • 方法区中静态变量、常量引用的对象。
      • JNI(Native 方法)引用的对象。
2. 垃圾回收算法
  1. 标记-清除(Mark-Sweep)

    • 流程:标记垃圾对象 → 清除。
    • 缺点:内存碎片化。
    • 应用场景:CMS 收集器的老年代回收。
  2. 复制(Copying)

    • 流程:将存活对象从 Eden 复制到 Survivor 区。
    • 优点:无碎片,适合存活率低的新生代。
    • 内存划分:Eden(80%)、Survivor0(10%)、Survivor1(10%)。
  3. 标记-整理(Mark-Compact)

    • 流程:标记存活对象 → 整理到内存一端 → 清除边界外内存。
    • 优点:无碎片,适合老年代。
    • 应用场景:Serial Old、G1 收集器。
  4. 分代收集(Generational)

    • 策略:新生代用复制算法,老年代用标记-清除或标记-整理。
    • 依据:对象存活周期不同(新生代对象生命周期短)。
3. 垃圾收集器
收集器特点适用场景
Serial单线程,简单高效客户端应用
Parallel Scavenge多线程,吞吐量优先后台计算任务
CMS低延迟,标记-清除,有内存碎片Web 应用
G1分 Region 管理,可预测停顿时间大内存应用
ZGC超低延迟(<10ms),支持 TB 级堆高并发实时系统

四、执行引擎

1. 解释器与 JIT 编译器
  • 解释器:逐行解释字节码,启动快但执行慢。
  • JIT 编译器(Just-In-Time):将热点代码编译为本地机器码,提升执行速度。
    • 热点探测:基于方法调用计数器、循环回边计数器。
    • 优化技术
      • 方法内联:将小方法调用替换为方法体代码。
      • 逃逸分析:若对象未逃逸出方法,直接在栈上分配。
      • 锁消除:移除线程安全的无竞争锁。
2. 分层编译(Tiered Compilation)
  • 层级
    • Level 0:解释执行。
    • Level 1:简单编译(C1 编译器,快速生成代码)。
    • Level 4:完全优化(C2 编译器,深度优化,耗时长)。
  • 目标:平衡启动速度和长期性能。

五、实战场景分析

1. Spring Boot 启动流程中的 JVM 行为
@SpringBootApplication
public class MyApp {
    public static void main(String[] args) {
        SpringApplication.run(MyApp.class, args); // 触发类加载、Bean 初始化
    }
}

@Service
public class UserService {
    static { System.out.println("静态代码块执行"); }
    public UserService() { System.out.println("构造方法执行"); }
}

输出

静态代码块执行  // 类初始化阶段
构造方法执行    // Bean 实例化阶段
  • 类加载:Spring 扫描到 @Service 注解时触发 UserService 类加载。
  • Bean 实例化:Spring 容器启动时创建单例 Bean,调用构造方法。
2. 内存泄漏排查

场景:静态集合持有对象导致无法回收。

public class MemoryLeak {
    private static List<byte[]> list = new ArrayList<>();
    public void addData() {
        list.add(new byte[1024 * 1024]); // 持续添加大对象
    }
}

排查步骤

  1. 使用 jps 查看 Java 进程 ID。
  2. 使用 jmap -dump:format=b,file=heap.hprof <pid> 生成堆转储文件。
  3. 使用 MAT(Memory Analyzer Tool) 分析 list 的引用链,定位泄漏点。

六、JVM 调优策略

1. 堆内存设置
  • 参数
    • -Xms:初始堆大小(如 -Xms512m)。
    • -Xmx:最大堆大小(如 -Xmx2g)。
  • 建议-Xms-Xmx 设为相同值,避免堆动态调整的开销。
2. 垃圾收集器选择
  • 高吞吐量-XX:+UseParallelGC(Parallel Scavenge + Parallel Old)。
  • 低延迟-XX:+UseG1GC(G1 收集器)或 -XX:+UseZGC(ZGC)。
3. 监控工具
  • jstat:监控 GC 统计信息。
    jstat -gcutil <pid> 1000  # 每秒输出一次 GC 统计
    
  • VisualVM:图形化监控堆、线程、CPU。
  • Arthas:在线诊断工具,支持方法调用追踪、热修复。

七、总结

JVM 的底层原理是 Java 生态高效运行的基石:

  1. 类加载:动态加载与安全隔离。
  2. 内存管理:堆与栈的分工,对象生命周期的精准控制。
  3. 垃圾回收:自动内存管理的核心,影响系统吞吐量与延迟。
  4. 执行引擎:解释与编译结合,实现高性能执行。

深入理解 JVM,不仅能优化应用性能(如减少 Full GC 停顿),还能有效排查内存泄漏、锁竞争等问题,是高级 Java 开发的必备技能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/979502.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HarmonyOS 5.0应用开发——多线程Worker和@Sendable的使用方法

【高心星出品】 文章目录 多线程Worker和Sendable的使用方法开发步骤运行结果 多线程Worker和Sendable的使用方法 Worker在HarmonyOS中提供了一种多线程的实现方式&#xff0c;它允许开发者在后台线程中执行长耗时任务&#xff0c;从而避免阻塞主线程并提高应用的响应性。 S…

《深度学习实战》第3集:循环神经网络(RNN)与序列建模

第3集&#xff1a;循环神经网络&#xff08;RNN&#xff09;与序列建模 引言 在深度学习领域&#xff0c;处理序列数据&#xff08;如文本、语音、时间序列等&#xff09;是一个重要的研究方向。传统的全连接网络和卷积神经网络&#xff08;CNN&#xff09;难以直接捕捉序列中…

10.【线性代数】—— 四个基本子空间

十、 四个基本子空间 1. 列空间 C ( A ) C(A) C(A) in R m R^m Rm2. 零空间 N ( A ) N(A) N(A) in R n R^n Rn3. 行空间 C ( A T ) C(A^T) C(AT) in R n R^n Rn4. 左零空间 N ( A T ) N(A^T) N(AT) in R m R^m Rm综述5. 新的向量空间 讨论矩阵 A m ∗ n A_{m*n} Am∗n​…

Windows上使用go-ios实现iOS17自动化

前言 在Windows上运行iOS的自动化&#xff0c;tidevice对于iOS17以上并不支持&#xff0c;原因是iOS 17 引入新通信协议 ‌RemoteXPCQUIC‌&#xff0c;改变了 XCUITest 的启动方式。 一、go-ios的安装 1、安装命令&#xff1a;npm i go-ios 2、安装完成后输入命令which io…

CBAM注意力机制详解与实现

前言&#xff1a; 在深度学习领域&#xff0c;注意力机制已成为提升模型性能的重要手段之一。CBAM&#xff08;Convolutional Block Attention Module&#xff09;作为一种轻量级且高效的注意力机制&#xff0c;被广泛应用于各种卷积神经网络中。 一、CBAM注意力机制概述 1.…

GCN从理论到实践——基于PyTorch的图卷积网络层实现

Hi&#xff0c;大家好&#xff0c;我是半亩花海。图卷积网络&#xff08;Graph Convolutional Network, GCN&#xff09;是一种处理图结构数据的深度学习模型。它通过聚合邻居节点的信息来更新每个节点的特征表示&#xff0c;广泛应用于社交网络分析、推荐系统和生物信息学等领…

给虚拟机配置IP

虚拟机IP这里一共有三个地方要设置&#xff0c;具体说明如下&#xff1a; &#xff08;1&#xff09;配置vm虚拟机网段 如果不进行设置&#xff0c;每次启动机器时都可能是随机的IP&#xff0c;不方便我们后续操作。具体操作是&#xff1a;点击编辑→虚拟网络编辑器 选择VMne…

【免费】YOLO[笑容]目标检测全过程(yolo环境配置+labelimg数据集标注+目标检测训练测试)

一、yolo环境配置 这篇帖子是我试过的&#xff0c;非常全&#xff0c;很详细【cudaanacondapytorchyolo(ultralytics)】 yolo环境配置 二、labelimg数据集标注 可以参考下面的帖子&#xff0c;不过可能会出现闪退的问题&#xff0c;安装我的流程来吧 2.1 labelimg安装 label…

mapbox基础,使用geojson加载heatmap热力图层

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性1.3 ☘️heatmap热力图层样式二、🍀使用geojs…

Python 课堂点名桌面小程序

一、场景分析 闲来无事&#xff0c;老婆说叫我开发一个课堂点名桌面小程序&#xff0c;给她在课堂随机点名学生问问题。 人生苦短&#xff0c;那就用 Python 给她写一个吧。 二、依赖安装 因为要用到 excel&#xff0c;所以安装两个依赖&#xff1a; pip install openpyxl…

蓝桥杯 路径之谜

路径之谜 题目描述 小明冒充 XX 星球的骑士&#xff0c;进入了一个奇怪的城堡。 城堡里边什么都没有&#xff0c;只有方形石头铺成的地面。 假设城堡地面是 nnnn 个方格。如下图所示。 按习俗&#xff0c;骑士要从西北角走到东南角。可以横向或纵向移动&#xff0c;但不能斜着走…

在鸿蒙HarmonyOS手机上安装hap应用

一、下载工具 安装hap包需要用到小工具 。 二、解压到目录后&#xff0c;进入该文件夹&#xff0c;打开命令行&#xff0c;如下图 三、将下载好的hap包放入刚才解压的文件夹内&#xff08;假设hap包文件名为app.hap&#xff09; 四、连接好手机和电脑&#xff0c;手机需要打…

Android APK组成编译打包流程详解

Android APK&#xff08;Android Package&#xff09;是 Android 应用的安装包文件&#xff0c;其组成和打包流程涉及多个步骤和文件结构。以下是详细的说明&#xff1a; 一、APK 的组成 APK 是一个 ZIP 格式的压缩包&#xff0c;包含应用运行所需的所有文件。解压后主要包含以…

自然语言处理:词频-逆文档频率

介绍 大家好&#xff0c;博主又来给大家分享知识了。本来博主计划完成稠密向量表示的内容分享后&#xff0c;就开启自然语言处理中文本表示的讲解。可在整理分享资料的时候&#xff0c;博主发现还有个知识点&#xff0c;必须得单独拎出来好好说道说道。 这就是TF-IDF&#xf…

esp8266 rtos sdk开发环境搭建

1. 安装必要的工具 1.1 安装 Git Git 用于从远程仓库克隆代码&#xff0c;你可以从Git 官方网站下载 Windows 版本的安装程序。安装过程中可保持默认设置&#xff0c;安装完成后&#xff0c;在命令提示符&#xff08;CMD&#xff09;或 PowerShell 中输入git --version&#…

pytest下放pytest.ini文件就导致报错:ERROR: file or directory not found: #

pytest下放pytest.ini文件就导致报错&#xff1a;ERROR: file or directory not found: # 如下&#xff1a; 项目文件目录如下&#xff1a; pytest.ini文件内容&#xff1a; [pytest] addopts -v -s --alluredir ./allure-results # 自动添加的命令行参数&#xff1a;# -…

Blender调整最佳渲染清晰度

1.渲染采样调高 512 2.根据需要 开启AO ,开启辉光 , 开启 屏幕空间反射 3.调高分辨率 4096x4096 100% 分辨率是清晰度的关键 , 分辨率不高 , 你其他参数调再高都没用 4.世界环境开启体积散射 , 可以增强氛围感 5.三点打光法 放在模型和相机45夹角上 白模 白模带线条 成品

Vllm进行Qwen2-vl部署(包含单卡多卡部署及爬虫请求)

1.简介 阿里云于今年9月宣布开源第二代视觉语言模型Qwen2-VL&#xff0c;包括 2B、7B、72B三个尺寸及其量化版本模型。Qwen2-VL具备完整图像、多语言的理解能力&#xff0c;性能强劲。 相比上代模型&#xff0c;Qwen2-VL 的基础性能全面提升&#xff0c;可以读懂不同分辨率和…

xr-frame 3D Marker识别,扬州古牌坊 3D识别技术稳定调研

目录 识别物体规范 3D Marker 识别目标文件 map 生成 生成任务状态解析 服务耗时&#xff1a; 对传入的视频有如下要求&#xff1a; 对传入的视频建议&#xff1a; 识别物体规范 为提高Marker质量&#xff0c;保证算法识别效果&#xff0c;可参考Marker规范文档 Marker规…

Windows环境下SuperMapGIS 11i 使用达梦数据库

1. 环境介绍&#xff1a; 1.1. 操作系统&#xff1a; windows server 2019 1.2. GIS 软件&#xff1a; 1.2.1. GIS 桌面 supermap-idesktopx-11.3.0-windows-x64-bin 下载链接&#xff1a;SuperMap技术资源中心|为您提供全面的在线技术服务 安装教程&#xff1a;绿色版&…