跳到主要内容
极客日志极客日志
首页博客AI提示词GitHub精选代理工具
搜索
|注册
博客列表
Javajava算法

Java 虚拟机核心机制:类加载与垃圾回收详解

综述由AI生成Java 虚拟机通过类加载机制管理类的生命周期,涵盖加载、验证、准备、解析和初始化等阶段。双亲委派模型确保了类的唯一性与安全性。对象创建涉及内存分配、零值初始化及构造器执行。垃圾回收(GC)自动管理内存,通过可达性分析判断对象存活状态。主流回收算法包括标记清除、标记整理和复制算法。新生代常用复制算法,老年代多用标记整理或并发清除。G1 收集器相比 CMS 在可预测停顿时间和内存碎片处理上更具优势,适合现代多核环境下的应用。

暖阳发布于 2026/3/16更新于 2026/4/296 浏览
Java 虚拟机核心机制:类加载与垃圾回收详解

1. 类初始化和类加载

1.1 创建对象的过程

在 JVM 中,创建一个新对象并非简单的内存分配,它包含几个关键步骤。当执行到 new 关键字时,JVM 会先检查目标类是否已加载。若未加载,则触发类加载流程;若已加载,则继续后续步骤。

接下来是在堆内存中分配空间,随后将对象实例变量初始化为零值(对象头除外)。之后需要对对象头进行必要的设置,比如记录哈希码、分代年龄等信息。最后,才会执行对应的构造方法(init 方法)。

  • 类加载:JVM 在执行到 new 关键字的时候,会先进行对应类的类是否加载,如果没有加载,那么就会先执行类加载,然后再执行 new 关键字。
  • 分配内存空间:在堆中分配一段空间给对应对象。
  • 初始化零值操作:给对象的空间内的对应成员初始化为零值(对象头除外)。
  • 进行必要的设置:比如说:给对象头设置一些信息,类的元数据,对象的年龄,对象的哈希码。
  • 执行 init 方法:执行对应的构造方法。

1.2 对象的生命周期

对象的生命周期可以概括为创建、使用、销毁三个阶段。

  • 创建:即上述的类加载与对象实例化过程。
  • 使用:调用该对象的成员方法或访问属性。
  • 销毁:当对象没有被引用了,就会被看作垃圾进行回收。

1.3 类加载器

JVM 提供了三种主要的类加载器,它们各司其职:

  • 启动类加载器:负责加载 Java 核心库里面的类,通常由 C++ 实现。
  • 扩展类加载器:加载一些扩展的类,比如说框架的类。
  • 应用程序类加载器:加载用户自己手动创建的类,也就是我们日常开发中最常接触的。

1.4 双亲委派模型

这是类加载器的核心原则,遵循'向上委派,向下加载'的策略。

如果一个类加载器收到了加载类的任务,不会自己先执行,而是往上委派给自己的父类,依次类推,直到委派给最终的父类也就是启动类加载器。然后从启动类加载器开始,判断该类是否被自己加载,如果能直接返回即可,如果不能继续往下加载(抛给子类),依次类推。

这种机制主要有以下作用:

  1. 保证类的唯一性:向上委派、向下加载的方式,保证了一个类不会被重复加载,并且保证一个类只会被一个类加载器加载。
  2. 保证安全性:如果用户自己编写了一些类,类的全限定名与 Java 核心库中的类一致,可能会出现优先加载用户的类,从而间接导致核心类被用户修改了。通过向上委派、向下加载的方式从上开始加载,保证了类的安全性。
  3. 形成了隔离和分层的效果:不同的类加载器负责不同的类,既不会重复加载,也保证了高效性。
  4. 简化了类加载流程:这种方式保证了一个类只能加载一次并且不同的类加载器负责不同的类,从而简化了流程。

1.5 类加载的过程

从大体上类加载分为五步:类加载、连接、初始化、使用、卸载。细分又有七步:类加载、验证、准备、解析、初始化、使用、卸载。

  • 类加载:通过类的全限定名找到对应的二进制字节码文件,将该文件转换到内存形成创建对象实例的模板。
  • 验证:验证该二进制字节码是否符合 JVM 规范,比如说校验魔术、主版本号等等。具体包括文件格式校验、元数据验证、字节码验证、符号引用验证。
  • 准备:给该类的静态变量赋一些初始化值。
  • 解析:将原来的符号引用转为直接引用。
  • 初始化:执行构造器方法,执行父类的静态成员、子类的静态成员、父类的构造方法、子类的构造方法。
  • 使用:用户使用。
  • 卸载:判断该类没有被引用即可卸载,主要看三个方面:该类里面的所有实例对象都已经被回收了、该类的 ClassLoader 对象已经被回收了、该类的实例没有被引用。

2. 垃圾回收

2.1 垃圾回收介绍

以前传统的开发人员需要进行一个对内存的手动释放,而垃圾回收就是可以自动的对内存进行回收。它既提高了开发效率,也避免了一些问题,比如内存溢出、内存泄漏。

2.2 触发垃圾回收的方式

GC 的触发方式主要有以下几种:

  1. 内存不足:当内存不足的时候,会触发直接垃圾回收机制。
  2. 手动执行:开发人员自己手动指定执行,例如调用 System.gc()。
  3. JVM 调参:通过调参可以来指定垃圾回收的行为。
  4. 内部策略:垃圾回收内部可能指定了创建对象的数量和内存使用情况,如果超过一定的阈值就会触发垃圾回收。

2.3 判断垃圾的方法

判断对象是否为垃圾主要有两种方法:

  • 引用计数法:给每次对象分配一个计数器,如果该对象被一个对象引用,那么就会将计数器进行加一。如果该对象没有被引用,那么此时计数器为 0,则被判断为可以被回收。不过这种方法无法解决循环引用的问题。
  • 可达性分析法:从 GC Root 出发找对应对象进行标记,如果有一个对象没有被标记(代表没有被直接引用或间接引用),那么该对象可以被回收。GC Root 对象包括:Java 的核心库类、调用本地方法的类、活跃线程的类等。

2.4 垃圾回收算法

主流的垃圾回收算法包括标记清除、标记整理和复制算法。

  • 标记清除算法:对引用的对象进行标记,然后进行清除。注意这里不是真正的清除,而是记录其对象的起始地址和结束地址到一个地址表中,下次要添加新对象时会先从表中找,找到一个适合大小的就会进行覆盖。好处是速度快,缺点是内存碎片化严重(内存不连续了,本来可以存入的对象存入不了)。
  • 标记整理算法:同理进行标记,然后再对可存活对象进行整理,最后清除。好处是避免了内存碎片化问题,缺点是速度慢。
  • 复制算法:将内存空间分为两份,一份存对象 from,一份为空 to。当要回收时,复制可存活对象移入为空的内存空间 to 中(移入既整理),然后对存对象的空间 from 整体清除,然后名称 from 和 to 换过来。好处是避免了内存碎片化问题,缺点是内存使用率不高。

2.5 垃圾回收器

根据作用范围不同,收集器也有所区别:

  • 新生代:Serial、ParNew、Parallel Scavenge,都是使用的复制算法。

  • 老年代:Serial Old(标记整理)、CMS(标记清除)、Parallel Old(标记整理)。

  • 整个堆:G1(整体标记整理,细分区域使用复制)。

  • Serial GC:串行的收集器。

  • ParNew/CMS:并行的收集器,重响应时间快的特点。

  • Parallel GC:并行的收集器,重吞吐量高的特点。

  • G1:并行的收集器,比较平衡。

2.6 minorGC、majorGC、fullGC

  • minorGC:

    • 范围:作用于新生代。
    • 作用时机:当新生代的 Eden 区空间无法装入新创建的对象时,就会触发一次 minorGC,并且每触发一次 minorGC,其存活对象的年龄加一。
    • 细节:作用时间短,次数多。
  • majorGC:

    • 范围:作用于老年代。
    • 作用时机:当新生代的对象需要移入老年代时,发现其空间不足,那么就会触发 majorGC。
    • 细节:作用次数不多,而不常使用。
  • fullGC:

    • 范围:作用于整个堆。
    • 作用时机:当新生代对象需要移入老年代时,发现其空间不足,会触发 minorGC,触发之后,如果还是老年代空间不足,那么就会触发 fullGC,对整体进行整理。
    • 细节:作用次数不多,作用时间长。

2.7 CMS 与 G1 的区别

方面CMSG1
作用范围作用于老年代作用于整个堆
STW 的时间CMS 是重响应时间快的,STW 的时间会更短G1 可以对 STW 时间进行一个可预测的操作
内存碎片化CMS 使用的是标记清除算法,会造成内存碎片化问题G1 使用的是标记整理算法,不会造成内存碎片化问题
垃圾回收过程初始标记、并发标记、重新标记、并发清理初始标记、并发标记、最终标记、筛选回收(如果并发标记中出现了对象引用改变,会将其对象引用存入一个队列中,直到最终标记时从队列进行进一步的筛选)
浮动垃圾它使用的是并发清理,那么如果垃圾回收的速度低于产生垃圾的速度,那么就会出现问题,从而导致 CMS 转变为 Serial,并且也由于在回收的过程中会产生一些浮动垃圾,因此需要一部分空间来存储对应的浮动垃圾它虽然也会产生垃圾,但是不会出现该问题,并且它是使用的多个垃圾回收器进行垃圾回收,效率更高

目录

  1. 1. 类初始化和类加载
  2. 1.1 创建对象的过程
  3. 1.2 对象的生命周期
  4. 1.3 类加载器
  5. 1.4 双亲委派模型
  6. 1.5 类加载的过程
  7. 2. 垃圾回收
  8. 2.1 垃圾回收介绍
  9. 2.2 触发垃圾回收的方式
  10. 2.3 判断垃圾的方法
  11. 2.4 垃圾回收算法
  12. 2.5 垃圾回收器
  13. 2.6 minorGC、majorGC、fullGC
  14. 2.7 CMS 与 G1 的区别
  • 💰 8折买阿里云服务器限时8折了解详情
  • 💰 8折买阿里云服务器限时8折购买
  • 🦞 5分钟部署阿里云小龙虾了解详情
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Claude Code 本地化配置指南:接入魔搭社区 API 实现国产模型调用
  • 本地部署 DeepSeek R1 模型并集成至 Dify 平台
  • 基于西门子TIA、PLCSIM Advanced与Kepware实现Fanuc机器人虚拟仿真调试
  • 人工智能基础:DIKWP 模型与学习路径
  • 大模型基本概念详解:定义、分类与发展历程
  • Rust 与 WebAssembly 深度实战:浏览器与 Node.js 的高性能融合
  • OpenAI Whisper 语音转文本实战指南
  • OpenClaw 开源项目实战:打造专属 AI 伴侣与图像生成
  • 基于 OpenClaw 与 Open WebUI 搭建企业多部门 AI 平台
  • 无人机遥感滑坡泥石流图像识别数据集介绍
  • 无成本安装配置 OpenClaw 龙虾 AI 全能助手
  • OpenClaw 龙虾 AI 全能助手安装与配置指南
  • 15 款互联网行业必备 AI 工具深度评测与推荐
  • 花生二手车交易平台全栈项目实战:Spring Boot 3 与 Vue 3 高并发架构
  • ChatGPT 插件生态爆发下的自动化写作与工具推荐方案
  • C++ 进阶:从裸指针到智能指针的内存管理进化
  • OpenClaw深度解析:“数字龙虾”何以引爆AI Agent时代?安全危机与未来之战
  • 基于 Spring Boot 的视频点播系统设计与实现
  • Trae 集成 Figma MCP 实现前端代码自动生成
  • 昇腾 NPU 部署 Llama 大模型:全流程实战与常见问题排查

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online