news 2026/5/5 5:54:33

带你了解JVM到底是什么(一)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
带你了解JVM到底是什么(一)

前言

对于Java 开发者而言,JVM(Java 虚拟机)是绕不开的核心底层基石。

我们写的.java源码,编译为.class字节码,并不直接在操作系统上运行,而是跑在 JVM 之上。

JVM 屏蔽了操作系统、硬件差异,实现了一次编写,到处运行;同时提供内存管理、垃圾回收、类加载、即时编译、并发内存模型全套能力。

一、JVM整体概述

1.什么是JVM

JVM是java虚拟机,本质上是一台抽象的、栈式指令集虚拟机,执行java字节码文件(.class)

2.核心特性

  • 跨平台:字节码统一,JVM 适配各系统(Windows/Linux/Mac)
  • 自动内存管理:开发者无需手动分配 / 释放内存
  • 垃圾回收 GC:自动回收无效对象,避免内存泄漏
  • 安全隔离:沙箱机制、类加载双亲委派安全隔离
  • 即时编译 JIT:热点代码编译为本地机器码,提升执行效率

3.JVM整体框架

标准 JVM 内部结构分为 5 大模块:

  1. 类加载器子系统:加载.class字节码到内存
  2. 运行时数据区:JVM 内存核心(堆、栈、方法区等)
  3. 执行引擎:解释器 + JIT 即时编译器,执行字节码
  4. 本地方法接口 JNI:调用本地 C/C++ 方法
  5. 本地方法库:底层系统原生方法库

执行流程:Java源码 → 编译器 → class字节码 → 类加载器 → 运行时数据区 → 执行引擎 → 机器指令执行

二、类加载子系统

类加载器的作用就是将字节码文件加载到JVM中,从而让Java程序能够启动起来

1.类加载全过程

一共有五个阶段:加载 → 验证 → 准备 → 解析 → 初始化

1)加载

读取.class字节码二进制数据、在内存方法区里创建Class对象、生成类元数据常量池

2)验证

保证字节码安全合法:文件格式验证、元数据验证、字节码验证、符号引用验证。

3)准备

为静态变量分配内存,并赋默认初始值,例如:

  • int → 0
  • boolean → false
  • 引用数据 → null:不赋程序员写的初始值

4)解析

符号引用替换为直接内存地址引用

5)初始化

真正执行静态代码块、静态变量赋值,触发类的主动加载

2.类加载器分类

1)启动类加载器 Bootstrap ClassLoader

C++ 实现,加载 JDK 核心基础类rt.jar

2)扩展类加载器 Extension ClassLoader

加载 jre/lib/ext 扩展包

3)应用程序类加载器 Application ClassLoader

加载开发者自己编写的Java类、第三方 jar

4)自定义类加载器

继承 ClassLoader,实现热部署、加密解密字节码

3.双亲委派模型(重点)

用于一句话来说流程就是:加载类时,先让上级试试,上级能加载就用上级的,上级加载不了,才自己动手

1)工作流程

当一个类要被加载时:

  1. 向上委托:自定义类加载器 → 父加载器 → 再父加载器 → 直到启动类加载器
  2. 向下反馈:启动类加载器加载不了 → 退回给扩展类加载器 → 再退回给应用类加载器 → 最后才由自定义类加载器加载

2)好处

  • 沙箱安全:防止 “山寨货” 冒充正品:比如你想自己写一个java.lang.String类冒充系统自带的。按照双亲委派,加载java.lang.String时,会先交给启动类加载器,它直接加载了系统自带的那个,根本轮不到你写的版本。这样就防止了恶意代码篡改系统核心类。

  • 类全局唯一:不管谁加载,只要类名一样,就会交给同一个加载器处理,保证一个类只被加载一次,不会出现两个一模一样的类打架。

  • 职责分层:谁的活谁干,不乱抢

    • 启动类加载器:只加载rt.jar里的系统核心类(比如java.lang.*
    • 扩展类加载器:只加载ext目录的扩展包
    • 应用类加载器:只加载你自己写的代码和第三方 jar分工明确,谁也不越界。

3)什么是破坏“双亲委派”

正常流程是 “先委托上级,再自己加载”,破坏双亲委派就是打破这个规则,不先找上级,直接自己加载

常见场景

  • 热部署:不停机更新代码,需要用自定义类加载器重新加载新版本类,不交给父加载器处理。
  • OSGi:模块化框架,每个模块有自己的类加载器,互相隔离,不走双亲委派。
  • SPI 机制:比如 JDBC,需要让应用类加载器反过来加载 SPI 接口的实现类,不遵循向上委托的规则。

三、JVM运行时数据区

JVM 启动后划分 5 大内存区域:程序计数器、虚拟机栈、本地方法栈、堆、方法区

1. 程序计数器(PC 寄存器)

线程私有,记录当前线程下一条要执行的字节码行号,唯一没有 OOM的内存区域(OOM就是内存溢出,当内存耗尽时会触发OOM)

作用:线程切换后恢复执行位置

2. Java 虚拟机栈(虚拟机栈)

线程私有,生命周期随线程;每个方法执行都会创建一个栈帧

栈帧包含:局部变量表、操作数栈、动态链接、方法出口

异常:

  • 栈深度过大:StackOverflowError

  • 栈动态扩容无法申请:OOM

3. 本地方法栈

作用和虚拟机栈类似,为Native 本地方法服务,同样会抛出栈溢出、OOM

4. 堆 Heap(最重要)

可以线程共享,JVM 最大内存区域;所有对象、数组实例都在堆上分配

唯一目的:存放对象,GC 垃圾回收主战场

堆内存划分:新生代 + 老年代

新生代:Eden 区 + Survivor0 + Survivor1

老年代:存放长期存活、大对象

5. 方法区(元空间 Metaspace)

  • 线程共享

  • 存放:类结构、常量池、方法字节码、静态变量、即时编译代码

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/5 5:47:28

AI智能体时代的第一道裂痕:MS-Agent高危漏洞背后的攻防博弈

当AI不再满足于陪你聊天,而是真正动手帮你整理文件、检索资料、甚至直接运行脚本——自主智能体时代便悄然到来了。这听起来很美好,直到你意识到:如果黑客能"说服"这个听话的数字助手去干坏事,会发生什么? …

作者头像 李华
网站建设 2026/5/5 5:46:29

当大模型遇见快马:体验从需求到成品的AI辅助开发完整闭环

最近尝试用AI辅助开发一个待办事项应用,整个过程就像有个编程助手全程陪跑,体验非常奇妙。这个项目不仅实现了基础的增删改查功能,还通过大模型的实时交互,让开发过程变得像对话一样自然。分享下这个有趣的实践: 从零到…

作者头像 李华
网站建设 2026/5/5 5:44:29

LangGraph 深度探索:打造企业级多Agent Open Deep Research 架构

在当前信息爆炸的时代,企业面临着海量数据的分析和决策挑战。传统的单一Agent模式在处理复杂、深度的研究任务时显得力不从心。基于LangGraph的多Agent协作架构应运而生,它通过将复杂任务分解为多个Agent协同完成,极大地提升了研究效率和深度…

作者头像 李华
网站建设 2026/5/5 5:39:48

告别Optane后,国产SCM存储卡Xlenstor2 X2900P实测:真能平替吗?

国产SCM存储卡Xlenstor2 X2900P深度评测:能否填补Optane退场后的空白? 当Intel在2022年宣布全面退出Optane业务时,整个存储行业都在寻找下一个能够弥合DRAM与NAND之间性能鸿沟的解决方案。三年过去,国产存储厂商大普微推出的Xlens…

作者头像 李华
网站建设 2026/5/5 5:37:30

3步解决B站字幕下载难题:BiliBiliCCSubtitle高效自动化工具

3步解决B站字幕下载难题:BiliBiliCCSubtitle高效自动化工具 【免费下载链接】BiliBiliCCSubtitle 一个用于下载B站(哔哩哔哩)CC字幕及转换的工具; 项目地址: https://gitcode.com/gh_mirrors/bi/BiliBiliCCSubtitle 还在为无法保存B站视频字幕而烦恼吗&#…

作者头像 李华
网站建设 2026/5/5 5:31:47

终极Happy Island Designer指南:5分钟快速打造梦想岛屿

终极Happy Island Designer指南:5分钟快速打造梦想岛屿 【免费下载链接】HappyIslandDesigner "Happy Island Designer (Alpha)",是一个在线工具,它允许用户设计和定制自己的岛屿。这个工具是受游戏《动物森友会》(Animal Crossing…

作者头像 李华