什么情况下对象会进入老年代?如何判断对象“是否存活”?
1 个回答
我一路种下蘑菇,只为让你知道回家的路。比比东# 对象何时进入老年代(典型路径) 1. **达到晋升年龄阈值(Tenuring)** Minor GC 时,从 Eden→Survivor 拷贝成功的对象年龄 `age+1`,当 `age ≥ MaxTenuringThreshold`(常见上限 15)即**晋升**到老年代。 2. **动态年龄判定(Dynamic Tenuring)** JVM 统计 Survivor 中各年龄段对象体量:当“≤ 某年龄 i 的对象总体积”**超过**当前 Survivor 区可用容量时,**年龄 ≥ i 的对象**会被提前整体晋升,以避免 Survivor 撑爆。 3. **Survivor 放不下 / 晋升失败(空间担保)** Minor GC 过程中,如果 Survivor 没空间承接,或老年代无足够空间接收应晋升对象,就会发生**分配/晋升失败**: * 能挪就**直接晋升**到老年代; * 挪不动可能触发 **Full GC**,甚至抛 OOM。 4. **大对象/巨型对象直接入老年代** * 在部分收集器与配置下,**非常大的对象**可**绕过新生代**直接分配到老年代(如 `PretenureSizeThreshold` 等配置对 Serial/ParNew+CMS 有效;G1 不支持该参数)。 * **G1 的“巨型对象(Humongous)”**(大小接近或超过一个 Region 的对象)直接在一串连续 Region 中分配,通常视作老年代的一部分来管理。 5. **Full GC 后的晋升/存活** Mixed/Full GC 过程中,仍存活且需要压缩/整理的对象被移动到老年代(或在老年代中重定位)。 # JVM 如何判断对象“是否存活” 核心是**可达性分析(Reachability)**,不是简单“引用计数”。 * **GC Roots 起点**:各线程栈上的本地变量/参数、JIT 寄存器中的活动引用、静态成员、常量池引用、JNI(本地代码)持有的引用、系统类加载器等。 * **从 Roots 可达 ⇒ 活对象;不可达 ⇒ 垃圾候选**。 结合 **四种引用强度**(自强到弱): * **强引用(Strong)**:可达就必然存活(不会被 GC 回收)。 * **软引用(Soft)**:内存吃紧时才回收;常用于缓存。 * **弱引用(Weak)**:下一次 GC 必回收(只要没有强/软引用链)。 * **虚引用(Phantom)**:不影响可达性,用于回收通知/资源清理(与 `ReferenceQueue` 配合)。 **终结(Finalization)/“复活”**: 对象第一次被判不可达,如覆盖了 `finalize()`(或 Cleaner 机制关联),可能被放入终结队列,在终结回调中“自救”把自己重新挂到可达链上(只会有一次机会)。之后再次不可达就会被正式回收。现代代码应避免依赖终结器。 **实现层面(理解即可)**: 标记-清除/标记-压缩算法与**三色标记**不变式(G1 用 SATB 写屏障、CMS 用增量更新)保证并发/增量标记的正确性;这都是为可达性分析服务。 # 现场如何“看得见” * **JDK 9+**:`-Xlog:gc*,age*` 可看晋升/年龄分布与各代用量。 * **JDK 8**:`-XX:+PrintGCDetails -XX:+PrintTenuringDistribution`。 * **jcmd**:`jcmd <pid> GC.heap_info`、`GC.class_histogram` 看各代体量/类分布。 * **JFR/Async-Profiler/MAT**:分析存活对象来源、引用链(找“为何活着”)。 # 备忘与误区 * **不能强行指定**“一定新生代/一定老年代”,晋升规则以收集器与当时内存形势为准。 * **G1** 没有传统意义的连续老年代大内存块;它以 Region 管理,晋升是“按 Region 搬家”。 * **System.gc()** 可能触发 Full GC,但是否压缩、是否晋升取决于收集器策略。 * **ZGC/Shenandoah** 在非分代模式下无“新生代/老年代”的划分(已支持分代变体,但语义不同);若你用的是它们,晋升逻辑不适用上述细节。 如果你在排查**老年代爆涨/频繁 Full GC**,优先看:Survivor 配比(`-XX:SurvivorRatio` / `-XX:TargetSurvivorRatio`)、`MaxTenuringThreshold`、对象年龄分布、巨型对象比例、以及是否存在“长链引用”导致的**意外存活**(用直方图与引用链一眼能看出来)。发布于 2025-08-19 02:03 •IP属地 内蒙古举报评论收藏
公众号进入网站体验更佳

