导航
只要对象“不可达”,在下一次 GC 时就会被回收。
和:
没有直接关系。
从 Root(全局对象、当前执行栈等)出发
还能不能访问到这块内存
能 → 活
不能 → 死
简化版:
栈(Stack)
堆(Heap)
├─ 新生代(New Space)
└─ 老生代(Old Space)
外部内存(C++ / Buffer)
| 类型 | 位置 |
|---|---|
| 基本类型(小) | 栈 or 堆 |
| 对象 / 数组 / 函数 | 堆 |
| 闭包捕获变量 | 堆 |
| Buffer / C++ 资源 | 外部内存 |
一句话:不可达 + GC 触发
通常:
Node 会自动做。
浏览器页面:
Node:
7 × 24 小时常驻进程
只要有一点点引用没断:
👉 内存只涨不降
最后:
FATAL ERROR: Reached heap limit
let arr = [];
while(true)
arr.push(1);
会不会爆?
✅ 一定爆。
为什么 GC 不回收?
因为:
arr → 一直存在
arr → 一直引用这些元素
永远可达。
GC 无法释放。
let arr = [];
while(true)
arr.push();
push() 什么都不传,相当于 push(undefined)
数组长度仍然增加。
所以:
arr.length 无限增长
仍然可达。
✅ 一样爆。
有区别吗?
比 push(1) 稍微省一点点。
但:
本质 = 无限扩容
逃不掉。
let arr = [];
while(true)
arr.push(new Buffer(1000));
🔥 这个更猛。
为什么更危险?
因为:
Buffer 的内存 ≠ 完全在 V8 堆内