news 2026/8/10 0:51:35

JVM-垃圾回收

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JVM-垃圾回收

一、先搞懂:JVM 为啥要做垃圾回收?

简单说,Java 程序运行时会在 JVM 堆内存里创建大量对象(比如new User()),那些不再被任何引用指向的对象就是 “垃圾”,如果不清理,内存会被占满导致程序崩溃。垃圾回收的核心目标:自动识别并清理堆中无用对象,释放内存,避免内存泄漏 / 溢出,不用像 C++ 那样手动free/delete

二、核心基础:怎么判断对象是 “垃圾”?

这是 GC 的第一步,常用 2 种方法:

1. 引用计数法(简单但有缺陷)
  • 逻辑:给每个对象加一个 “引用计数器”,有引用指向它就 + 1,引用断开就 - 1;计数器为 0 就是垃圾。
  • 坑:无法解决循环引用(比如 A 引用 B,B 引用 A,两者都没用但计数器都不为 0),JVM 实际不用这种方法。
2. 可达性分析算法(JVM 主流)
  • 逻辑:以 “GC Roots” 为起点(比如虚拟机栈里的局部变量、静态变量、JNI 引用等),向下遍历引用链;没有被连接到的对象就是垃圾。
  • 举个栗子:

    java

    运行

    public void test() { User u1 = new User(); // u1是GC Roots(局部变量),User对象可达,不是垃圾 u1 = null; // 引用断开,User对象不可达,标记为垃圾 User u2 = new User(); User u3 = u2; u2 = null; // u3还引用User对象,仍可达,不是垃圾 }

三、垃圾回收的 “核心动作”:分代回收(堆内存分区)

JVM 把堆分成 “新生代” 和 “老年代”,因为不同对象的生命周期不同,用不同策略回收更高效:

区域特点回收策略核心回收器
新生代对象创建快、死亡快(90% 对象短命)频繁 Minor GC(轻量回收)Serial/ParNew/Parallel Scavenge
老年代存活久的对象(从新生代存活下来)低频 Major GC/Full GC(重量级)CMS/G1/ZGC/Shenandoah
关键流程(以最经典的 “复制算法” 为例):

新生代又分 1 个 Eden 区 + 2 个 Survivor 区(S0/S1):

  1. 新对象先放 Eden 区,Eden 满了触发 Minor GC,存活对象复制到 S0,清空 Eden;
  2. 下次 Minor GC,Eden+S0 的存活对象复制到 S1,清空 Eden+S0;
  3. 反复几次后,还存活的对象 “晋升” 到老年代;
  4. 老年代满了触发 Major GC/Full GC,清理老年代垃圾(耗时久,会导致程序卡顿)。

四、常见垃圾回收器(新手必知)

不同回收器适配不同场景,核心看 “吞吐量” 和 “停顿时间”:

1. Serial GC(串行回收器)
  • 单线程回收,只适合单核 / 小内存场景(比如桌面程序、嵌入式),优点是简单、内存占用少,缺点是停顿久。
2. Parallel Scavenge(并行回收器)
  • 多线程回收新生代,追求 “高吞吐量”(运行程序时间 / 总时间),适合后台计算型程序(比如大数据处理),默认 JDK8 的新生代回收器。
3. CMS(并发标记清除)
  • 老年代回收器,主打 “低停顿”(用户几乎感知不到 GC),分 4 步:初始标记→并发标记→重新标记→并发清除;
  • 缺点:会产生内存碎片,占用 CPU 资源,JDK9 开始被标记为废弃。
4. G1 GC(Garbage First)
  • JDK9 默认回收器,把堆分成多个小块,优先回收垃圾多的块,兼顾吞吐量和停顿时间,适合大内存场景(比如 8G 以上堆),是目前主流。

五、新手常见误区

  1. 误区 1:GC 会回收所有无用对象 → 错!GC 只能回收堆内存的对象,栈、方法区的资源(比如线程、静态变量)管不了;
  2. 误区 2:Full GC 是手动调用System.gc()触发的 → 错!System.gc()只是 “建议” JVM 回收,JVM 可以忽略;Full GC 通常是老年代满、永久代 / 元空间满等触发;
  3. 误区 3:GC 停顿越短越好 → 错!要平衡:比如实时系统(电商支付)要低停顿,后台计算要高吞吐量。

总结

  1. JVM 垃圾回收核心是识别无用对象(可达性分析)+ 分代清理(新生代 / 老年代),避免手动管理内存;
  2. 判断垃圾的核心算法是可达性分析,而非引用计数(解决循环引用问题);
  3. 常见回收器各有侧重:Serial(单核)、Parallel(吞吐量)、CMS(低停顿)、G1(兼顾),实际开发中 G1 是主流选择。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/4 11:51:32

低功耗设计:手机控制LED屏的节能策略

手机控制LED屏如何省电?揭秘三大低功耗核心技术你有没有想过,一块小小的LED显示屏,为什么能让智能手环撑上一周,而有些电子标签却几个月都不换电池?在物联网设备遍地开花的今天,手机通过蓝牙控制LED屏已经不…

作者头像 李华
网站建设 2026/7/31 6:26:02

MyBatis实战精讲:完整用户CRUD操作全解析

在Java持久层开发领域,MyBatis凭借其轻量化、高灵活性的特性,成为连接Java应用与数据库的主流框架。它摒弃了JDBC繁琐的代码编写,通过“接口XML”的映射模式,让开发者专注于SQL逻辑本身。本文将基于一套完整的用户数据操作代码&am…

作者头像 李华
网站建设 2026/8/5 5:02:14

【2025 arXiv】Reasoning Within the Mind: Dynamic Multimodal Interleaving in Latent Space

这篇论文的核心突破在于将多模态推理从“显式的文本生成”转移到了“隐式的潜在空间优化”,并利用“置信度”这一信号实现了类似人类的动态视觉回溯,从而兼顾了推理的深度、准确性和效率。 paper: https://arxiv.org/pdf/2512.12623 code: https://github.com/eric-ai-lab/DM…

作者头像 李华
网站建设 2026/8/4 1:24:34

构建安全可控的企业知识库:anything-llm解决方案

构建安全可控的企业知识库:anything-llm解决方案 在企业数字化转型的浪潮中,一个现实问题正日益凸显:员工每天花数小时翻找政策文件、客服重复回答相同问题、新成员难以快速掌握内部流程——信息就在那里,却“看得见、摸不着”。传…

作者头像 李华
网站建设 2026/8/2 11:03:39

工业控制中CCS安装的实战案例解析

工业控制中CCS安装的实战案例解析:从零搭建稳定开发环境在工业自动化项目中,一个稳定、高效的嵌入式开发环境,往往决定了产品迭代的速度和系统调试的成败。而当我们选用TI C2000系列DSP作为主控芯片时,Code Composer Studio&#…

作者头像 李华
网站建设 2026/8/8 22:08:22

【参数估计】基于WSO算法的太阳能光伏模型参数估计附Matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室🍊个人信条:格物致知,完整Matlab代码及仿真咨询…

作者头像 李华