跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava算法

Java 垃圾回收机制详解

Java 垃圾回收机制自动管理堆内存,通过识别无用对象释放空间。主要判断算法包括引用计数法和可达性分析算法。常用回收算法有标记 - 清除、复制、标记 - 整理及分代收集。常见垃圾回收器包括 Serial、Parallel、CMS 和 G1,各自在吞吐量、停顿时间及内存利用率上有所不同。

忘忧发布于 2026/2/4更新于 2026/7/251.4K 浏览
Java 垃圾回收机制详解

1. Java 垃圾回收概述

垃圾回收(Garbage Collection,GC)是 Java 虚拟机自动管理堆内存的机制,负责识别不再使用的对象并释放其占用的内存。

垃圾回收的触发机制如下:

  • 内存不足时: 当 JVM 检测到堆内存不足,无法为新的对象分配内存时,会自动触发垃圾回收。
  • 手动请求: 虽然垃圾回收是自动的,开发者可以通过调用 System.gc() 或 Runtime.getRuntime().gc() 建议 JVM 进行垃圾回收。不过这只是一个建议,并不能保证立即执行。
  • JVM 参数: 启动 Java 应用时可以通过 JVM 参数来调整垃圾回收的行为,比如:-Xmx(最大堆大小)、-Xms(初始堆大小)等。
  • 对象数量或内存使用达到阈值: 垃圾收集器内部实现了一些策略,以监控对象的创建和内存使用,达到某个阈值时触发垃圾回收。

2. Java 垃圾回收判断算法

引用计数法

基本原理: 为每个对象分配一个专有的引用计数器,当一个对象被引用后,计数器 +1,引用失效后,计数器 -1,计数器为 0 时,表示对象不再被任何变量引用,可以被回收。

这个算法非常简单易懂,可是它有一个致命的缺点,就是循环引用的问题。

// 一个简单的循环引用例子
class RefObject {
    public Object instance = null;
}
public class Main {
    public static void main(String[] args) {
        RefObject objA = new RefObject();
        RefObject objB = new RefObject();
        objA.instance = objB;
        objB.instance = objA;
        objA = null;
        objB = null;
    }
}

可以看到,当 objA 和 objB 设置为 null 时,正常来说应该被垃圾回收,可是由于 objA 被 objB 引用,objB 被 objA 引用,导致计数器不为 0 无法被回收,这就是循环引用的问题所在。所以大部分情况我们都是使用下面这种算法。

可达性分析算法

基本原理: 通过一系列称为'GC Roots'的根对象作为起始节点,从这些根节点开始,根据引用关系向下搜索,如果某个对象到 GC Roots 间没有任何引用链相连,则证明此对象是不可用的,可以被回收。

它与引用计数法最核心的区别在于:它不关心对象被引用了多少次,只关心能否从根节点触达。

该算法从根本上解决了循环引用的问题。在上面的例子中,虽然 A 和 B 互相引用,但只要它们无法从 GC Roots 到达,就会被判定为垃圾。

话又说回来了,难道可达性分析算法就没用缺点吗?

从原理那我们也不难看出,可达性分析算法的实现相比于引用计数法更加复杂了,同时,为了保证分析结果的准确性,在进行可达性分析时,必须在一个一致性快照中进行。这意味着在分析期间,整个执行系统必须被冻结,不允许对象的引用关系发生变化。这个过程就是著名的 Stop The World(STW),是垃圾收集器产生停顿的主要原因之一。


3. Java 垃圾回收算法

标记 - 清除算法

基本原理: 先标记所有存活对象,再清除未标记对象。

一个简单的实现如下:

// 算法伪代码示意
public class MarkSweep {
    void mark(Object obj) {
        if (obj != null && !obj.isMarked()) {
            obj.setMarked(true);
            mark(obj.references);
        }
    }
    void sweep(Heap heap) {
        for (Object obj : heap.objects) {
            if (!obj.isMarked()) {
                heap.free(obj);
            } else {
                obj.setMarked(false);
            }
        }
    }
}

该算法简单直接,不过效率不高而且会产生内存碎片。

复制算法

基本原理: 内存分成两块,每次申请内存时都使用其中的一块,当内存不够时,将这一块内存中所有存活的复制到另一块上。然后将然后再把已使用的内存整个清理掉。

该算法解决了不会产生内存碎片的问题,可又带来了新的问题:每次申请内存时只能申请一半的内存空间,内存利用率严重不足。

标记 - 整理算法

基本原理: 标记 - 整理算法的'标记'过程与'标记 - 清除算法'的标记过程一致,但标记之后不会直接清理。而是将所有存活对象都移动到内存的一端。移动结束后直接清理掉剩余部分。

该算法既解决了内存碎片问题的产生,也提高内存利用率,不过整理阶段需要移动对象,开销较大。

分代收集算法

基本原理: 分代收集是将内存划分成了新生代和老年代。分配的依据是对象的生存周期,或者说经历过的垃圾回收次数。对象创建时,一般在新生代申请内存,当经历一次 GC 之后如果对还存活,那么对象的年龄 +1。当年龄超过一定值 (默认是 15)后,如果对象还存活,那么该对象会进入老年代。

不同分代使用的回收机制也不用,我们来介绍下这两种内存划分

新生代:

  • Eden 区(80%):新对象分配区
  • Survivor 区(20%):Minor GC 后存活对象存放区
  • 使用复制算法,回收频率高,由于新生代对象存活率低,该算法效率较高。

老年代:

  • 存放长期存活对象
  • 使用标记 - 清除或标记 - 整理算法

4. Java 中常见的垃圾回收器

Serial 收集器

  • 垃圾回收算法:复制算法
  • 特点:单线程,简单高效
  • 工作模式:暂停所有用户线程(STW),进行垃圾回收

JVM 配置示例:

# JVM 参数 -XX:+UseSerialGC

Parallel 收集器

实际上是 Serial 收集器的多线程版本

JVM 配置示例:

# JVM 参数 -XX:+UseParallelGC # 新生代 Parallel Scavenge,老年代 Serial Old
# -XX:+UseParallelOldGC # 新生代 Parallel Scavenge,老年代 Parallel Old
# -XX:+UseParNewGC # 新生代 ParNew,需配合 CMS 使用
# -XX:ParallelGCThreads=n # 设置并行 GC 线程数

适合对延迟不敏感,高吞吐量需求的场景。

并发标记清除回收器 (CMS)

老年代并行收集器,以获取最短回收停顿时间为目标的收集器,具有高并发、低停顿的特点,追求最短 GC 回收停顿时间。

收集过程:

  1. 初始标记:STW,标记 GC Roots 直接关联对象
  2. 并发标记:与应用程序并发,遍历整个对象图
  3. 重新标记:STW,修正并发标记期间的变动
  4. 并发清除:与应用程序并发,清理死亡对象

JVM 配置示例:

# JVM 参数 -XX:+UseConcMarkSweepGC
# -XX:CMSInitiatingOccupancyFraction=68 # 老年代使用率触发阈值
# -XX:+UseCMSCompactAtFullCollection # 开启碎片整理

相应的,CMS 回收器也有部分缺点,如对 CPU 资源敏感,无法处理浮动垃圾(并发时新产生的垃圾),内存碎片问题(标记 - 清除算法)

G1 回收器

这是目前使用率最高的垃圾回收器,它做了一个革命性的设计:不再物理分代,而是逻辑分区的 Region,此外,G1 收集器不同于之前的收集器的一个重要特点是:G1 回收的范围是整个 Java 堆 (包括新生代,老年代),而前几种收集器回收的范围仅限于新生代或老年代。

下面是 G1 垃圾回收器的基本流程:

JVM 配置示例:

# JVM 参数 -XX:+UseG1GC
# -XX:MaxGCPauseMillis=200 # 目标最大停顿时间
# -XX:G1HeapRegionSize=n # Region 大小(1M~32M,2 的幂)

目录

  1. 1. Java 垃圾回收概述
  2. 2. Java 垃圾回收判断算法
  3. 引用计数法
  4. 可达性分析算法
  5. 3. Java 垃圾回收算法
  6. 标记 - 清除算法
  7. 复制算法
  8. 标记 - 整理算法
  9. 分代收集算法
  10. 4. Java 中常见的垃圾回收器
  11. Serial 收集器
  12. JVM 参数 -XX:+UseSerialGC
  13. Parallel 收集器
  14. JVM 参数 -XX:+UseParallelGC # 新生代 Parallel Scavenge,老年代 Serial Old
  15. -XX:+UseParallelOldGC # 新生代 Parallel Scavenge,老年代 Parallel Old
  16. -XX:+UseParNewGC # 新生代 ParNew,需配合 CMS 使用
  17. -XX:ParallelGCThreads=n # 设置并行 GC 线程数
  18. 并发标记清除回收器 (CMS)
  19. JVM 参数 -XX:+UseConcMarkSweepGC
  20. -XX:CMSInitiatingOccupancyFraction=68 # 老年代使用率触发阈值
  21. -XX:+UseCMSCompactAtFullCollection # 开启碎片整理
  22. G1 回收器
  23. JVM 参数 -XX:+UseG1GC
  24. -XX:MaxGCPauseMillis=200 # 目标最大停顿时间
  25. -XX:G1HeapRegionSize=n # Region 大小(1M~32M,2 的幂)
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

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

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

更多推荐文章

查看全部
  • OpenClaw 联网工具配置与使用指南
  • 3D Max VR 渲染器局部渲染设置教程
  • 基于 Open-AutoGLM 的手机自动化部署与实战指南
  • VSCode Copilot 登录失败常见原因与高效解决方案
  • Claude Code 安装与使用实录
  • JDK21 下载与安装指南
  • OpenClaw 开源 AI Agent 框架本地部署全流程
  • 2025 WAIC 探展:合合信息 AI 鉴伪技术洞察伪造痕迹
  • SpringBoot+Vue 社区医院管理系统设计与实现
  • VLA 机器人模型解析:10 篇关键视觉 - 语言 - 动作论文
  • 华为 OD 机试双机位 C 卷 - 评委评分算法题
  • 本地部署 ComfyUI 运行 Stable Diffusion 3.5-FP8
  • C++ 事件总线(EventBus)实现嵌入式系统解耦
  • 基于 Java 与 Vue 的大学生理财记账贷款系统
  • Android System WebView 内核版本更新方法
  • Stable Diffusion 与 Z-Image-Turbo 部署对比:推理速度与显存占用评测
  • LangChain 安装与使用指南:从 LLM 链到检索链
  • 基于高阶控制障碍函数的端到端无人机高速避障方法
  • LangGraph Studio 可视化调试基于 LangGraph 构建的 AI 智能体
  • 知网 AIGC 检测价格对比与省钱策略

相关免费在线工具

  • 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