javascript引擎不使用引用计数作为主gc机制,因其无法处理循环引用;它通过计数器跟踪引用数,归零即刻回收,但现代引擎采用可达性分析(如mark-sweep)从根出发标记并回收不可达对象,天然解决循环引用问题。

JavaScript 引擎不使用引用计数算法作为主垃圾回收机制,但理解它对看清内存管理本质很有帮助——它不是“被弃用的错误方案”,而是一个逻辑清晰、响应及时、但能力受限的设计。
引用计数怎么工作
每个对象内部带一个整数计数器,只看“有多少变量或结构正指着它”:
- 变量赋值、入数组、传参、作为属性被持有 → 计数 +1
- 变量重赋值、离开作用域、显式 del(虽 JS 中无此语法,但类似行为如赋值为 null 或 undefined)→ 计数 −1
- 计数降为 0 时,内存立即释放,不等待任何扫描周期
循环引用为什么卡死计数器
两个对象彼此持有对方,外部已无其他引用,但计数器永远无法归零:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- A 对象里有 this.b = B,B 的计数 +1
- B 对象里有 this.a = A,A 的计数 +1
- 当 a 和 b 变量被销毁后,A 和 B 的计数仍各为 1
- 垃圾回收器只认数字,不分析结构——只要不是 0,就判定“还在用”
现代 JavaScript 实际怎么处理
V8 等主流引擎完全不用引用计数,而是采用“可达性分析”(Mark-Sweep / Mark-Compact):
- 从全局对象、当前执行栈等“根”出发,追踪所有能访问到的对象
- 未被追踪到的对象,哪怕互相引用,也视为不可达,直接回收
- 天然解决循环引用问题,无需额外检测环
- IE 6–8 的 DOM/BOM 曾用引用计数,正是因循环引用导致严重内存泄漏,后来被彻底淘汰
为什么还要学它
它揭示了一个关键事实:内存管理没有银弹。引用计数快而确定,适合实时场景;可达性分析鲁棒但需暂停(stop-the-world)或增量处理。理解它的边界,才能写出更可控的对象关系——比如避免在事件监听器、缓存结构或状态树中无意构造强引用闭环。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










