← 每日面试题 学习看板

什么是跨代引用,有什么问题?

面试题/00java/03JVM/05分代与GC触发条件/什么是跨代引用,有什么问题?.md

面试记录 2026-10-16

题目:什么是跨代引用,有什么问题?

难度:low

标签:jvm/gc, general/knowledge, difficulty/low

评分:⭐⭐☆☆☆(2/5)

我的回答

跨代引用指的是年轻代的对象引用了老年代的对象,或者老年代的对象引用了年轻代的对象,这时候年轻的对象进行ygc的时候无法正常回收,没法回收老年代的空间,导致空间无法正常释放,对象可能会直接从年轻代进入老年代

点评

优点:

不足:

补充:跨代引用是单向的(Old→Young),通过 Remembered Set/Card Table + 写屏障解决。

完整讲解

第一部分:知识重点剖析

核心考点定位:考察对跨代引用的严格定义、问题本质和解决机制的理解。

知识点拆解:

  1. 跨代引用的严格定义:特指老年代对象引用新生代对象(Old→Young,不是双向),不是"年轻代引用老年代"
  2. 问题本质:FullGC 时若从老年代 GC Roots 遍历新生代,需要扫描整个新生代,O(n) 爆炸(新生代通常 1/3 堆大小,扫描成本高)
  3. 解决机制:Remembered Set(G1,每个老年代 Region 维护跨到年轻代的引用集合)+ Card Table(CMS/Parallel,每 512 字节标记一个 Card,写屏障时更新 Card 状态)+ 写屏障(对象引用赋值时的检查代码,让 GC 高效处理并发修改)

第二部分:考察方向与延伸递进

考察方向:

延伸递进面试题:

  1. Remembered Set 和 Card Table 有什么区别?
  1. 写屏障在跨代引用中起什么作用?
  1. 为什么跨代引用不是双向的?

第三部分:面试者参考回答(三步法口语化,300-400 字)

【一句话结论】

面试官您好,跨代引用特指老年代对象引用新生代对象,FullGC 时若全堆遍历会 O(n) 爆炸,通过 Remembered Set/Card Table + 写屏障解决。

【三点展开】

第一,跨代引用是单向的,特指 Old→Young 引用,不是双向的。Young→Old 引用是正常的,FullGC 时会扫描。问题只在 Old→Young:FullGC 时若从老年代 GC Roots 遍历新生代,需要扫描整个新生代,O(n) 爆炸(新生代通常 1/3 堆大小)。

第二,解决机制有两种:G1 用 Remembered Set,每个老年代 Region 维护一个跨到年轻代的引用集合,FullGC 时只扫描这些集合里的引用,避免全堆遍历。CMS/Parallel 用 Card Table,每 512 字节标记一个 Card,写屏障在对象引用赋值时更新 Card 状态,FullGC 时只扫描"脏"的 Card。

第三,写屏障是关键:对象引用赋值时插入的检查代码,如果新引用指向新生代对象,更新 Card Table 或 Remembered Set。这样 GC 可以高效处理并发修改,避免全堆扫描。

【一句边界】

当然,跨代引用不是双向的。Young→Old 引用是正常的,FullGC 时会扫描。问题只在 Old→Young,因为从老年代 GC Roots 遍历新生代会 O(n) 爆炸。另外,G1 的 Region 设计让跨代引用问题更容易管理(Remembered Set 按 Region 维护)。