JS垃圾回收机制

文章目录

  • 垃圾回收机制
    • 引用计数法
      • 引用计数原理
      • 引用计数过程
      • 引用计数缺点——循环引用
    • 标记清除法
      • 标记阶段
      • 清除阶段
      • 循环引用

垃圾回收机制

JS 垃圾收集器每隔一段时间就对变量检查。当一个变量不再被需要时,它就会把这个变量所占用的内存空间给释放掉,以防内存泄漏。

内存泄漏:内存泄漏并不是物理层面上的泄露,是指变量再使用的过程中没有被及时的销毁、内存空间没有被释放,导致内存占用不断攀高,带来性能恶化、系统崩溃等一系列问题的现象。

JS 垃圾回收算法有两种:引用计数法、标记清除法。

引用计数法

引用计数法是最初级的垃圾回收算法,现代浏览器几乎不使用。

引用计数就是记录每个值被引用的次数。

引用计数原理

内存中的每一个值都会对应一个引用计数。当垃圾收集器感知到某个值的引用计数为 0 时,这块内存就会被释放。

引用计数过程

当声明了一个变量并将一个引用类型值赋值该变量时,则这个值的引用次数就是1;

	var arr = [1];   //arr变量引用为1

var
如果同一个值又被赋给另外一个变量,则该值得引用次数加1;

	var arr1 = arr;   //arr变量引用为2

相反,如果包含对这个值引用的变量又取得了另外一个值,则这个值的引用次数为 1;

	var arr1 = [2];   //arr变量引用为1

当这个值的引用次数变成 0时,则说明没有办法再访问这个值了,因而就可以将其占用的内存空间回收回来。

	var arr = null;   //arr变量引用为0, arr被回收

引用计数缺点——循环引用

obj1引用obj2,而obj2也引用obj1。

function fun(){     
    var obj1 = new Object();
    var obj2 = new Object(); 
    obj1.a = obj2;
    obj2.b = obj1; 
} 

obj1和obj2的引用次数都是2,函数执行后,两个对象还将继续存在,它们的引用次数永远不会为0。

标记清除法

由于引用计数法存在循环引用问题,所有浏览器都采用了标记清除算法。

使用标记清除算法时, 未引用对象不会被立即回收,而是累计到内存耗尽程序将会被挂起时, 开始执行清理所有的未引用对象后程序再继续执行。

在标记清除算法中,一个变量是否被回收的判断标准,是它是否 “可访问 ”。标记清除算法有两个阶段:标记阶段、清除阶段。

标记阶段

垃圾收集器会先找到根对象(在浏览器里,根对象是 Window;在 Node 里,根对象是 Global),然后从根对象出发,扫描所有可以通过根对象直接(或者间接)访问的对象,这些对象会被标记为 “可访问”。

清除阶段

没有被标记为 “可访问” 的变量,就是不需要的变量,会被回收清除。

循环引用

obj1引用obj2,而obj2也引用obj1。

function fun(){     
    var obj1 = new Object();  //obj1 就是 Window.obj1 “可访问”
    var obj2 = new Object();  //obj2 就是 Window.obj2 “可访问”
    obj1.a = obj2;
    obj2.b = obj1; 
} 

标记清除算法中,函数执行后,两个对象都离开了作用域 “不可访问”,obj1、obj2被回收,因此相互引用不是问题。

你可能感兴趣的:(JavaScript,javascript,垃圾回收机制)