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;
}
上面示例中的 objA
和 objB
的引用次数永远不会变为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;