JVM 垃圾回收:小区垃圾清运队,面试再问也不慌

2026/11/05 Java

故事场景:一个只进不出的小区

把 JVM 的堆想成一个小区:

  • 年轻代 = 新楼盘:天天有人搬进来,也天天有人搬走,流动极快;
  • 老年代 = 老小区:住进来就不轻易走,住户稳定,但一旦要清理,动静就大;
  • 垃圾回收器 = 清运队:定期进小区,把没人要的东西清走,腾出地方给新人住。

JVM 不像 C 语言那样让你自己倒垃圾——对象没人引用了,清运队就该来。但问题来了:清运队怎么知道哪件东西“没人要了”?

第一问:怎么判断一个对象死了?

新手常背“引用计数法”:每个对象头上挂个计数器,有人指着它就 +1,没人指就 -1,归零就是垃圾。

这个办法听起来直观,JVM 却没用它,原因是一个死结:两个人互相指着对方,但小区外已经没人认识他们了。计数器永远不归零,垃圾就永远清不掉。这叫循环引用,引用计数法栽就栽在这里。

JVM 用的办法叫可达性分析:先定几个“活口”当起点,顺着引用链一路走,能走到的就是活物,走不到的就是垃圾。

这几个起点叫 GC Roots,面试常考,记住四类就够:

  1. 虚拟机栈里的局部变量:正在跑的方法里用到的对象;
  2. 方法区的静态变量:类里 static 修饰的引用;
  3. 方法区的常量引用:比如字符串常量池里的引用;
  4. 本地方法栈里的 JNI 引用:Native 方法持有的对象。

一句话:从 GC Roots 出发,顺藤摸不到瓜的,就是垃圾。

第二问:为什么要分代?

因为小区里住户的“寿命”极不均匀:绝大多数对象朝生暮死——方法里 new 一个临时对象,用完就扔;极少数对象活得很久——缓存、连接池、单例。

如果每次清运都把整个小区翻一遍,成本太高。所以 JVM 按寿命分代,区别对待:

  • 年轻代(Eden + 两个 Survivor 区):新对象先住 Eden,活过一次 GC 就搬进 Survivor,搬来搬去几次还活着,才“晋升”到老年代;
  • 老年代:住的都是老住户,清理频率低得多,但一次清理的代价大。

经验数字不用死记,记住趋势:年轻代朝生暮死、回收频繁但便宜;老年代稳定长寿、回收稀少但昂贵。

第三招:清运队有哪几种清法?

  1. 标记-清除:先把活物打勾,没打勾的直接清走。简单,但清完后空地是碎的——大件家具(大对象)想搬进来,找不到一整块空地;
  2. 复制:把活物原样抄到另一块空地,整块旧地一次性清空。没有碎片问题,但要多留一半空地,适合年轻代这种“活物少、死物多”的地方——年轻代的两个 Survivor 区就是这么轮换着用的;
  3. 标记-整理:先打勾,再把活物往一头挪齐,剩下的整块空地一次清掉。没有碎片,也不用留空地,但挪东西要花时间,适合老年代。

年轻代用复制、老年代用标记-整理,这就是分代收集的经典搭配。G1、ZGC 这些新收集器思路更细,但面试先把这三招讲清,就已经够用了。

第四问:Minor GC 和 Full GC,到底差在哪?

  • Minor GC:只清年轻代。频繁,但因为年轻代死物多、活物少,清得快,对业务停顿影响小;
  • Full GC:连老年代、方法区一起清。少见,但一次动静大,停顿时间长,是线上最怕见到的那种。

还有一个面试高频词:STW(Stop The World)。清运队进场时,为了防止“刚判定是垃圾、下一秒又被捡回去”的乌龙,大多数收集器会先让所有业务线程暂停一下。停顿时间越短,用户体感越好——这也是新一代收集器一直在优化的方向。

一张表记住今天的内容

问题 一句话答案
怎么判断对象死了? 可达性分析:从 GC Roots 出发走不到的,就是垃圾;引用计数法败在循环引用
为什么分代? 对象寿命极不均匀,年轻代朝生暮死、老年代长寿稳定,区别对待才划算
三种清法各适合哪? 标记-清除简单但留碎片;复制无碎片但费一半空间,适合年轻代;标记-整理无碎片不费空间但挪动花时间,适合老年代
Minor 和 Full 的区别? Minor 只清年轻代、快而频繁;Full 连老年代一起清、少见但停顿大

文末留一句话

下次面试官问“JVM 垃圾回收讲讲”,别从算法名词开始背,先讲这个小区:谁是住户、谁是清运队、怎么判断东西没人要了——故事立住了,算法名词自然就贴得上去。


和这篇搭着看:想看清运队干活的”真实记录”长什么样,见我早年写的《可视化GC日志分析》——那篇是拿真实 GC 日志逐行解读,和这篇正好一个讲原理、一个看实战。

动手验证:给 JVM 加上 -XX:+PrintGCDetails 跑一跑,亲眼看看 Minor GC 和 Full GC 在日志里的区别,比背十遍定义都直观。想在云上练手可以看我整理的云服务器选购指南,新客首单很便宜,别买贵了;对日志、转时间戳这类小活儿,我的在线工具箱 itupload.cn 打开就能用。

Show Disqus Comments

Search

    Post Directory