js中的垃圾回收机制

Posted hygcoding

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了js中的垃圾回收机制相关的知识,希望对你有一定的参考价值。

js中所谓垃圾,一般来说指的是无法被访问到的内存,不同于偏向底层的C,js会有一套固定的算法,定期地清除这些垃圾,防止出现内存泄漏,本篇文章首先会介绍什么样的内存区域会被定义为垃圾,接下来会介绍几个常见的垃圾回收算法。

何为垃圾


1.没有被任何内容引用的对象


我们来看下面这段代码

var x={name="first"};
x={name="second"};

首先变量x指向了一个名为first的对象(这里不严谨地将对象的name属性作为该对象的代号),接下来它改变指向,指向了一个新的,名为second的对象,之前的first对象无法被访问到,系统会将其判定为垃圾。


2.互相引用,但他们作为一个整体无法被外界引用到的对象


这种情况也是导致引用计数算法出错的根源,看如下代码:

function comb(x,y){
    x.friend=y;
    y.friend=x;
    return {left:x,right:y};
}
var x={name:"a"};
var y={name:"b"};
var father=comb(x,y);

该代码用变量father指向两个对象x和y,而通过函数comb,将x和y相互绑定
技术图片

 

 此时,如果执行如下操作:

father.left=null;
father.right=null;

则尽管x和y都有被引用,但是x和y的整体无法被访问到,一样会被视为垃圾。

 

3.对于基本数据类型变量


这个相对引用类型会更好理解,即刚进入环境的变量不会被视为垃圾,但是退出环境的变量即视为垃圾,也就是说,一个局部变量一旦脱离了创建他的环境(可以出现在该环境内的子环境中),就会被视为垃圾,进行回收。典型的例子就是函数中定义的局部变量,当函数执行完毕后,这些变量就会被释放。
由于在栈中,函数结束后本身就会释放堆栈内存,所以这种垃圾并不在我们经常讨论的范围内,一般垃圾回收的对象都是堆中的对象。

 

GC算法


一.标记-清除算法

算法步骤:
1.标记内存中的所有内容
2.将根及其所有可访问到的后代清除标记
3.删除所有含标记的内容

缺点:
会产生大量碎片,影响内存的使用效率

二.标记-压缩算法


与标记-清除算法的不同之处在于会将非垃圾在堆中集中靠前,这样的操作避免的大量碎片的产生,但是在时间效率上过低,因为要在堆中移动对象。

三.引用计数法


作为最原始的垃圾回收算法,其主要步骤如下:
1.每个对象都维护一个引用计数值,用于表示当前该对象被多少变量引用了
2.该对象每次赋值给一个新变量,计数值+1
3.每次引用该对象的变量有了新的对象,引用值-1
4.如果某时该对象计数值为0,视为垃圾,清除之

缺点:无法处理上述循环引用的问题

该方法由于缺陷,在较新版本的浏览器中已不使用。

 

以上是关于js中的垃圾回收机制的主要内容,如果未能解决你的问题,请参考以下文章

Python 中的垃圾回收机制

谈谈垃圾回收机制方式内存管理?

垃圾回收机制与内存管理

Javascript的垃圾回收机制

javascript中的垃圾回收机制

JavaScript性能优化1——内存管理(JS垃圾回收机制引用计数标记清除标记整理)