尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

别再搞混了!JVM的Minor GC、Major GC、Full GC 到底有啥区别?

别再搞混了!JVM的Minor GC、Major GC、Full GC 到底有啥区别?
📅 发布时间:2026/7/1 1:35:58

写这篇的起因是复习的时候看到这三个概念,脑子一片浆糊,参考的复习资料写的也不清楚,很模糊。后来花时间整理了一遍,发现其实没那么复杂,写出来给跟我一样曾经懵逼的同学。


先别急,搞清楚 JVM 堆里有啥

要理解这三种 GC,首先得知道 JVM 堆内存是怎么分的。不用记太细,看个大概就行:

┌──────────────── 堆(Heap) ─────────────────┐ │ │ │ ┌─────────────────┐ ┌───────────────┐ │ │ │ 年轻代 │ │ 老年代 │ │ │ │ (Young Gen) │ │ (Old Gen) │ │ │ │ │ │ │ │ │ │ ┌─────┐ ┌────┐ │ │ 存放"老油条" │ │ │ │ │Eden │ │Surv│ │ │ 久经考验还没 │ │ │ │ │ │ │ivor│ │ │ 死掉的对象 │ │ │ │ └─────┘ └────┘ │ │ │ │ │ └─────────────────┘ └───────────────┘ │ └──────────────────────────────────────────────┘
  • 年轻代:又分成 Eden(伊甸园)和两个 Survivor(幸存者区)。新创建的对象基本都在 Eden 区。

  • 老年代:存放那些"活了很久"的对象,从年轻代熬过来的。

  • 永久代/方法区:java8之后就不在堆中了,移动到本地内存的元空间中,存储类信息、静态变量、常量、编译后的代码

记住这个就够了,下面我们一个一个说。


Minor GC(又称 Young GC) —— 年轻代的"日常清扫"

它管哪里?

只管年轻代(Eden + Survivor),跟老年代没关系。

什么时候触发?

Eden 区满了,没地方放新对象了,就会触发一次 Minor GC。

它怎么干活?

打个比方:Eden 就像一个会议室,人(对象)进进出出。会议室满了,保安(GC)进来清场——活着的人挪到隔壁 Survivor 区,没用的直接赶走(回收)。每活过一轮,年龄 +1,到了一定年龄(默认 15),就有资格去老年代混了。

Eden 满了 → 存活对象复制到 Survivor → 年龄够了 → 晋升老年代

特点

  • 发生频率很高,你的程序一直在创建对象,所以 Minor GC 是常客

  • 速度快,因为年轻代里大部分对象都是"短命鬼",存活的少,回收很快

  • STW(Stop-The-World)时间短,通常毫秒级,用户基本无感知


Major GC —— 老年代的"大扫除"

它管哪里?

只管老年代。

什么时候触发?

老年代空间不够用了。通常是年轻代的对象一个个晋升过来,老年代装不下了。

它怎么干活?

老年代里的对象都是"老油条"了,存活率高,所以不能像年轻代那样简单复制。通常用的是标记-清除或者标记-整理算法:

  • 标记-清除:先标记哪些还活着,把死的清掉(但会产生内存碎片)

  • 标记-整理:标记之后,把活的对象往一端挪,剩下的空间就是连续的

特点

  • 频率比 Minor GC 低很多,毕竟老年代不是那么容易满

  • 速度比 Minor GC 慢,因为活着的对象多,处理起来费劲

  • STW 时间更长,这里就要注意了

说实话,Major GC 这个概念在不同语境下含义不太一样。有的资料里它特指只回收老年代,有的时候它跟 Full GC 混着用。面试的时候如果被问到,你最好反问一句"您说的是只回收老年代还是整堆回收"——这反而显得你懂行。


Full GC —— 真正的"搬家公司"

它管哪里?

整个堆(年轻代 + 老年代)+Metaspace(方法区),全部清扫一遍,一个都不放过。

什么时候触发?

触发条件比较多,常见的几种:

  1. 老年代空间不足

  2. Metaspace(方法区)空间不足

  3. 代码里调了System.gc()(建议 JVM 做一次 Full GC,JVM 可以拒绝,但一般不会)

  4. Minor GC 后要晋升到老年代,但老年代放不下

  5. CMS 收集器并发阶段搞砸了(Concurrent Mode Failure)

特点

  • 频率最低,但每次搞都是大事

  • 耗时最长,因为要把整个堆翻一遍

  • STW 时间最长,这个才是性能杀手

重点来了

你做 JVM 调优,最重要的目标之一就是:减少 Full GC 的频率,缩短 Full GC 的时间。因为一次 Full GC 卡个几百毫秒甚至几秒,用户端就可能感觉到卡顿了。


一张表帮你记住

Minor GCMajor GCFull GC
回收哪年轻代老年代整个堆 + Metaspace
啥时候触发Eden 满了老年代满了多种情况
多久一次很频繁不太频繁很少(希望如此)
快不快快较慢最慢
STW 多长短较长最长

进阶:老年代不足时,到底触发的是 Major GC 还是 Full GC?

这里有个很多人搞不清楚的点,包括很多博客也写得含糊。

先说一个常见的理解:

老年代不足 → 先触发 Major GC → 搞不定(内存不足且无法扩展) → 再触发 Full GC

听起来很有道理对不对?但实际情况没这么简单。

Major GC 和 Full GC 并不总是这种"先后触发"的关系。真正的答案是:取决于你用的是哪个垃圾收集器。不同的收集器,面对"老年代不足"这件事,处理方式完全不一样。

下面分三种情况来说:

情况一:Parallel / Serial 收集器

用这类收集器时,老年代空间不足,直接触发 Full GC。

没有先 Major GC 一轮、不行再 Full GC 的过程。上来就是 Full GC,年轻代老年代一起清。日志里看到的是这样的:

[Full GC (Allocation Failure) [PSYoungGen: 2048K->0K(28672K)] [ParOldGen: 65536K->63000K(69632K)] 67584K->63000K(98304K)]

注意关键字Allocation Failure,说明就是因为分配失败直接 Full GC 了,没给你来一轮 Major GC 热身的机会。

情况二:CMS 收集器

CMS 的处理方式就比较接近前面那个"先后触发"的理解了:

老年代使用达到阈值(默认92%) │ ▼ CMS 启动并发标记清除(这个 ≈ Major GC) │ ├── 成功 → 搞定,程序继续跑 │ └── 失败(Concurrent Mode Failure) │ ▼ 退化为 Full GC(整堆回收,STW)

CMS 会在老年代还没完全满的时候就提前开始并发回收,如果回收速度跟得上对象晋升的速度,皆大欢喜。但如果跟不上,老年代还是溢出了,就会出现Concurrent Mode Failure,然后退化成 Full GC。

情况三:G1 收集器

G1 又是另一套逻辑。G1 把堆划分成了很多个 Region,它不严格区分年轻代和老年代的单独回收:

Young GC(回收年轻代 Region) │ ▼ 并发标记(后台标记老年代存活对象) │ ▼ Mixed GC(同时回收年轻代 + 部分老年代 Region) │ └── Mixed GC 也搞不定 → Full GC(兜底)

G1 里你很少看到 Major GC 这个说法,它用的是Mixed GC这个概念。万一 Mixed GC 也救不了场,才会退化为 Full GC。

总结一下这个关系

用一张图说清楚:

老年代不足时,触发什么? │ ├── Parallel / Serial ──→ 直接 Full GC │ ├── CMS ──→ 先并发回收老年代(≈ Major GC) │ └── 搞砸了 → Full GC │ └── G1 ──→ Mixed GC(同时回收年轻代 + 部分老年代 Region) └── 搞不定 → Full GC

所以说,Major GC 和 Full GC 的触发关系不是固定的,它跟你选的收集器强相关。面试的时候如果你能把这一层说出来,直接跟别人拉开差距。


记忆技巧

我自己的记忆方式,分享一下:

Minor = 小,只扫年轻代这一小块地方。Major = 大,扫老年代这块大地方。Full = 满/全,全部扫一遍,地毯式清理。

或者你这样想:

  • Minor GC= 每天倒垃圾桶,随手的事

  • Major GC= 每周做一次大扫除,稍微累点

  • Full GC= 搬家前的彻底清扫,累死人,而且你还不想太频繁搬家


实战:看看 GC 日志长啥样

你在启动参数里加上 GC 日志,就能看到这些信息:

JDK 8:

-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:gc.log

JDK 9 及以上:

-Xlog:gc*:file=gc.log:time,uptime,level,tags

日志里看到类似这样的就是 Minor GC:

[GC (Allocation Failure) [PSYoungGen: 65536K->1024K(76288K)] 65536K->1025K(251392K), 0.005 secs]

看到类似这样的就是 Full GC:

[Full GC (Ergonomics) [PSYoungGen: ...] [ParOldGen: ...] ...->...(...K), 0.08 secs]

注意看关键字:GC一般是 Minor,Full GC明确写了 Full。多看几次日志你就熟悉了。


还有几点容易踩的坑

1. Minor GC 也会触发 Full GC

不要觉得 Minor GC 就是小事。如果 Minor GC 后存活对象要晋升到老年代,但老年代放不下,就会触发 Full GC。所以老年代的空间规划很重要。

2. 不要随便写System.gc()

有些同学调试的时候喜欢加System.gc(),这东西在生产环境就是个定时炸弹,它会建议 JVM 做一次 Full GC。

3. 不同垃圾收集器行为不一样

G1 收集器里其实不太区分 Minor/Major GC,它的概念是 Mixed GC。ZGC、Shenandoah 这些新收集器更是做到了几乎不感知的 GC 停顿。所以面试问你的时候,你可以说"传统分代收集器下有这三种区分",然后补一句"但 G1/ZGC 等新收集器有自己的 GC 阶段划分"——这就很加分了。


最后再来个总结

新对象出生在 Eden │ Eden 满了 → Minor GC(只扫年轻代,快) │ 活下来的进 Survivor,反复熬 │ 熬够次数 → 晋升老年代 │ 老年代满了 → 具体触发什么,看收集器: │ ├── Parallel/Serial → Full GC │ ├── CMS → Major GC(搞砸了再 Full GC) │ └── G1 → Mixed GC(搞不定再 Full GC) │ 无论如何 → Full GC 都是最后的杀手锏,尽量别让它出现

理解了这条链路,这三个概念你就彻底理清了。

相关新闻

  • 基于单片机智能点滴控制系统智能输液非接触式液位检测心率监测33(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码
  • 【Claude】Claude Code CLAUDE.md 记忆系统完全指南:让 AI 永远记得你的项目规范
  • 基于STM32单片机甲烷煤气天然气报警厨房安全火灾报警火焰物联网3(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码

最新新闻

  • 深度测评2026年AI论文工具:这几款让论文写作不再是难题
  • 最新量化验证,回测模拟实盘不是一件事
  • 大数据志愿填报冲稳保如何搭配院校梯度
  • open harmony 项目实战:给语文学习 App 做一个高端精致的沉浸式界面
  • Sa-Token:48,800+ Star 的背后让鉴权变得简单优雅
  • PHP+VUE医疗预约系统毕业设计:全栈开发实战与部署指南

日新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

周新闻

  • Windows字体自定义终极方案:No!! MeiryoUI完全指南
  • Deepin Boot Maker:告别命令行,3分钟制作Linux启动盘的智能解决方案
  • Plain Craft Launcher 2:重新定义你的Minecraft游戏体验

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号