js中的垃圾回收机制

221 阅读2分钟

js中的垃圾回收机制的原理:

概述

目的

为了以防内存泄漏。

含义

解决内存的泄露,垃圾回收机制会定期(周期性)找出那些不再用到的内存(变量),并释放掉它们所指向的内存。

变量的生命周期

当一个变量的生命周期结束之后它所指向的内存就应该被释放。 JS有两种变量,全局变量和在函数中产生的局部变量。局部变量的生命周期在函数执行过后就结束了,此时便可将它引用的内存释放(即垃圾回收),但全局变量生命周期会持续到浏览器关闭页面。

现在各大浏览器通常采用的垃圾回收机制有两种方法:标记清除(mark and sweep)、引用计数(reference counting)。

两种方法

标记清除:

大部分浏览器以此方式进行垃圾回收,当变量进入执行环境(函数中声明变量)的时候,垃圾回收器将其标记为“进入环境”,当变量离开环境的时候(函数执行结束)将其标记为“离开环境”,在离开环境之后还有的变量则是需要被删除的变量。标记方式不定,可以是某个特殊位的反转或维护一个列表等。

垃圾收集器给内存中的所有变量都加上标记,然后去掉环境中的变量以及被环境中的变量引用的变量的标记。在此之后再被加上的标记的变量即为需要回收的变量,因为环境中的变量已经无法访问到这些变量。

function

test(){ 
 var a = 10 ; //被标记 ,进入环境 
 var b = 20 ; //被标记 ,进入环境 
} 

test(); //执行完毕 之后 a、b又被标离开环境,被回收。

引用计数:

这种方式常常会引起内存泄漏,低版本的IE使用这种方式。机制就是跟踪一个值的引用次数,当声明一个变量并将一个引用类型赋值给该变量时该值引用次数加1,当这个变量指向其他一个时该值的引用次数便减一。当该值引用次数为0时就会被回收。

但是很重要的一点是当遇到循环引用的时候,函数的引用次数就不会为0,所以不会被垃圾回收器回收内存,会造成内存泄露。在IE中涉及COM对象,就会存在循环引用的问题。


function

test(){ 
 var a = {} ; //a的引用次数为0 
 var b = a ; //a的引用次数加1,为1 
 var c =a; //a的引用次数再加1,为2 
 var b ={}; //a的引用次数减1,为1 
}

参考 拓展