JavaScript 垃圾回收机制知识点笔记

3 阅读1分钟

JS垃圾回收

JavaScript 通过自动内存管理实现高效的内存分配和闲置资源回收。其垃圾回收机制主要依赖于两种标记策略:标记清除(Mark-and-Sweep)和引用计数(Reference Counting)。

标记清除

标记清除是 js 最常用的垃圾回收策略,给变量标记的方式有很多种。

垃圾回收程序运行时,会标记内存中存储的所有变量,然后会将上下文的变量及被这些变量引用的变量的标记去掉;之后再被标记的变量便是待删除,即在上下文中该变量已不被访问。垃圾回收程序进行内存清理时,会销毁带标记的所有值并回收其所占用的内存。

引用计数

引用计数是对每个值都记录其被引用的次数,当值的引用次数为0时,垃圾回收程序运行时会将引用次数为 0 的值得内存释放。

引用计数存在一个严重的问题:循环引用。

function fun() {
    let objA = new Object();
    let objB = new Object();
    objA.b = objB;
    objB.a = objA;
}

上面示例中的 objAobjB 的引用次数永远不会变为0, 在引用计数策略下其内存无法被回收。

若函数 fun 被多次调用,会导致大量内存无法释放。

在 IE8 及更早版本,BOM 和 DOM 中的对象是 C++ 实现的 COM 对象,COM 对象使用的是引用计数实现垃圾回收,即使 js 引擎使用标记清除,在存取 COM 对象时因为使用引用计数,则无法避免循环引用问题。

let el = document.getElementById('test');
let myObj = new Object();
myObj.el = el;
el.obj = myObj;

解决处理:

myObj.el = null;
el.obj = null;