导航


HTML

CSS

JavaScript

浏览器 & 网络

版本管理

框架

构建工具

TypeScript

性能优化

算法

UI、组件库

Node

业务技能

针对性攻坚

AI

软实力


JavaScript 中不同类型以及不同环境下变量的内存都是何时释放?

只要对象“不可达”,在下一次 GC 时就会被回收。

和:

没有直接关系。


GC 判断的唯一核心标准:

从 Root(全局对象、当前执行栈等)出发
还能不能访问到这块内存

能 → 活

不能 → 死


V8 内存大体怎么分(必须知道)

简化版:

栈(Stack)
堆(Heap)
   ├─ 新生代(New Space)
   └─ 老生代(Old Space)
外部内存(C++ / Buffer)

存什么?

类型 位置
基本类型(小) 栈 or 堆
对象 / 数组 / 函数
闭包捕获变量
Buffer / C++ 资源 外部内存


什么时候会被释放?

一句话:不可达 + GC 触发


GC 什么时候触发?

通常:

Node 会自动做。


为什么 Node 更容易出问题?

浏览器页面:

Node:

7 × 24 小时常驻进程

只要有一点点引用没断:

👉 内存只涨不降

最后:

FATAL ERROR: Reached heap limit

几个“爆内存”的示例和解析

情况 1

let arr = [];
while(true)
  arr.push(1);

会不会爆?

✅ 一定爆。


为什么 GC 不回收?

因为:

arr → 一直存在
arr → 一直引用这些元素

永远可达。

GC 无法释放。


情况 2

let arr = [];
while(true)
  arr.push();

push() 什么都不传,相当于 push(undefined)

数组长度仍然增加。

所以:

arr.length 无限增长

仍然可达。

✅ 一样爆。


有区别吗?

比 push(1) 稍微省一点点。

但:

本质 = 无限扩容

逃不掉。


情况 3(重点)

let arr = [];
while(true)
  arr.push(new Buffer(1000));

🔥 这个更猛。


为什么更危险?

因为:

Buffer 的内存 ≠ 完全在 V8 堆内