javascript中的垃圾回收机制
Posted 十九万里
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javascript中的垃圾回收机制相关的知识,希望对你有一定的参考价值。
为什么需要垃圾回收
js不像C/C++ 有自己的一套垃圾回收机制(Garbage Collection)前端的叫法就是GC
js的解释器可以检测到何时程序不在使用一个对象,确定一个对象没有用的时候,就会启动这个垃圾回收机制
详细分析:
由于js中字符串,对象和数组没有固定的大小,所以当他们的大小已经知道的时候,才能对他们进行动态的存储分配,
js每次创建字符串,数组,对象的时候,解释器都必须分配内存来占用那个实体,,每次创建都会分配一次,可想而知,分配的次数多了之后,系统中的内存消耗完,然后系统奔溃 game over!!
垃圾回收的方法
常见的:
标记清除
计数引用
不常见的:
GC复制法
保守式GC
分代回收
增量式GC
三色标记法
下面就来写一下两种常见的垃圾回收机制
垃圾回收方法一 标记清除
标记清除是最常见的垃圾回收机制,当变量进入环境之后,就标记这个变量为“进入环境”,从逻辑上来说 被标记了“进入环境”的变量永远不会被释放(清除),离开环境的时候,标记“离开环境”,
原理:
垃圾回收器在运行的时候就会给存储在内存中的变量都加上标记,环境变量中的变量是不受影响的,被环境变量引用的变量也是安全的(条件性去除标记),
然删除所有标记了“离开环境”的变量,清除他们所占的内存
标记清除算法从名称上看,可以拆分为两部分:标记(mark)和清除(sweep)。
此算法可以分为两个阶段,一个是标记阶段,一个是清除阶段,下面就分别做一下介绍。
1).标记阶段:
在此阶段,垃圾回收器会从mutator(应用程序)根对象开始遍历。
每一个可以从根对象访问到的对象都会被添加一个标识,于是这个对象就被标识为可到达对象。
2).清除阶段:
在此阶段中,垃圾回收器会对堆内存从头到尾进行线性遍历,如果发现有对象没有被标识为可到达对象,那么就将此对象占用的内存回收,并且将原来标记为可到达对象的标识清除,以便进行下一次垃圾回收操作
IE、Firefox、Opera、Chrome、Safari的js实现使用的都是标记清除的垃圾回收策略或类似的策略,只不过垃圾收集的时间间隔互不相同
垃圾回收机制二 计数引用
计数引用的意思就是记录每个值没被引用的次数
当我们声明一个变量之后,并且一个引用类型的值赋值给了该变量,那么就计算出这个值的引用次数为1;
如果这个引用类型的值在之后又取得了另外一个值,那么计数次数减一,目前就是0;
当我们声明的这个变量引用值为0的时候。说明这个变量已经没用了,所以垃圾回收器再次运行的时候 就把引用次数为0的值回收其内存。
语言引擎有一张"引用表",保存了内存里面所有资源(通常是各种值)的引用次数。如果一个值的引用次数是0,就表示这个值不再用到了,因此可以将这块内存释放。
计数引用带来的几个问题?
上面说到变量的引用值变为0的时候,就会产生计数引用垃圾回收机制
那么在两个函数相互引用的时候,作用完成之后离开作用域,此时变量已经没用了,应当被回收,但是由于相互引用,它的引用值并没有变成0,所以不会被回收,如果代码中存在大量的引用就会造成内存泄漏。
解决办法:手动释放内存
在使用函数相互引用或者闭包的时候,手动释放函数。
以上是关于javascript中的垃圾回收机制的主要内容,如果未能解决你的问题,请参考以下文章