GC 怎么判定“该回收谁”:GC Roots、可达性分析、四种引用与回收算法
很多人学 GC 的痛点是名词一堆标记清除、复制、标记整理、分代但一旦你真遇到“内存回不去”你又不知道该从哪里解释这篇把 GC 的主线拆成两条先判定谁活谁死可达性分析再决定怎么回收算法/策略1. 为什么 JVM 不用引用计数循环引用是天坑引用计数思路每个对象维护引用次数变成 0 就回收问题两个对象互相引用引用次数永远不为 0但它们可能已经“不可达”所以 HotSpot 主流使用可达性分析Reachability Analysis2. 可达性分析从 GC Roots 出发能走到就是活核心规则从一组根对象GC Roots出发遍历对象图能到达的对象都是存活到达不了的对象就是垃圾2.1 常见 GC Roots 你至少要认识线程栈中的引用局部变量表静态变量引用被类持有的引用JNI 引用本地方法栈运行中的线程对象、Class 对象等不同实现有差异这也是为什么静态集合很容易造成“你以为没用了但其实一直活着”3. 回收算法标记清除 / 复制 / 标记整理3.1 标记清除Mark-Sweep标记出要回收的对象直接清除问题产生碎片3.2 复制算法Copying把存活对象复制到另一块连续空间直接清理整块旧空间特点回收快、无碎片需要额外空间常见用法新生代对象存活率低复制成本低3.3 标记整理Mark-Compact标记存活对象把存活对象往一侧挪整理成连续空间特点减少碎片整理有成本常见用法老年代存活率高复制成本高4. 分代收集不是算法是“策略组合”分代思想来自经验大多数对象活不久所以新生代复制/快速回收老年代标记整理或标记清除 处理碎片5. 四种引用为什么你“以为能回收”但没回收5.1 强引用默认写法就是强引用只要强引用还在通常不会回收5.2 软引用SoftReference内存紧张时才回收常用于缓存但别把它当万能缓存方案5.3 弱引用WeakReference下一次 GC 就可能被回收常见场景弱引用缓存、ThreadLocal 的 key5.4 虚引用PhantomReference不影响对象生命周期常用于“对象被回收前做通知/资源清理”这类高级用法6. 把这些知识落到排障你该如何解释“内存回不去”你遇到“Full GC 后内存回不去”你可以按这个顺序解释先确认是不是有 GC Roots 在引用静态集合/线程栈/ThreadLocal再确认存活对象是否真的很多业务缓存/大对象最后用 heapdump MAT 找到引用链7. 总结HotSpot 主要用可达性分析从 GC Roots 出发判定存活回收算法标记清除碎片/复制快/标记整理少碎片分代是策略组合新生代与老年代采用不同回收方式四种引用决定“对象在不同内存压力下是否会被回收”
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2427610.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!