理解js的垃圾回收机制这个问题,不管是对于以后的面试,还是在js的开发工作往更深一层走的话都是有很大的帮助

垃圾回收

平常js的开发过程中,我们所创建的基本数据类型和引用数据类型,要都是需要开辟内存空间才能运行的,否则就会存在内存溢出、泄露之类的风险。
要知道的是:js中的内存管理是对用户不可见的,且自动执行的。
关注点:js引擎如何处理我们不再需要的那些数据类型从而释放内存,这就是js的垃圾回收机制。

什么样的数据会被回收

简单来说,一个数据类型的声明周期结束之后,就会被回收,他的内存也会被释放。
全局变量生命周期会持续到会话关闭
局部变量的生命周期在函数执行完毕之后就结束了

经常被提起的两种js垃圾回收方式

标记清除
大部分浏览器用这种方法进行垃圾回收。当变量被声明进入js的执行环境,垃圾回收器对其进行标记状态“进入环境”,在变量结束生命周期后标记为“离开环境”。
带有“在当前执行环境中的变量”标记的变量都不会被清除,其他的变量都会被清除回收。
它会去掉处在环境中的变量及被环境中的变量引用的变量标记(闭包)。而在此之后剩下的带有标记的变量被视为准备删除的变量
垃圾回收机制是按照一定的周期运行的
“根”的概念
还有一种解释方法是说明“根”的概念
https://segmentfault.com/a/11...

引用计数
低版本的ie使用这种方式,会有内存泄露的风险。
机制为跟踪变量的引用次数:声明变量并将一个引用类型赋值给该变量时该值引用次数加1,当这个变量指向其他值时该值的引用次数便减1,引用次数为0时进行回收。
该方式会引起内存泄漏的原因是它不能解决循环引用的问题

function sample(){
    var a={};
    var b={};
    a.prop = b;
    b.prop = a;
}

这种情况下每次调用sample()函数,a和b的引用计数都是2,会使这部分内存永远不会被释放,即内存泄漏。

低版本IE中有一部分对象并不是原生JS对象。例如,其BOM和DOM中的对象就是使用C++以COM(Component Object Model)对象的形式实现的,而COM对象的垃圾收集机制采用的就是引用计数策略。

因此即使IE的js引擎是用的标记清除来实现的,但是js访问COM对象如BOM,DOM还是基于引用计数的策略的,也就是说只要在IE中设计到COM对象,也就会存在循环引用的问题。

对于全局或者一直存在于执行环境中的变量,需要时可以手动置空释放内存


ClearBoth
25 声望3 粉丝

Hello World!