JavaScript 的内存泄露和垃圾回收

什么是内存泄露 ?

  • 任何编程语言,在运行时都须要使用到内存,好比在一个函数中, var arr = [1, 2, 3, 4, 5]; 这么一个数组,就须要内存。javascript

  • 可是,在使用了这些内存以后, 若是后面他们不会再被用到,可是尚未及时释放,这就叫作内存泄露(memory leak)。若是出现了内存泄露,那么有可能使得内存愈来愈大,而致使浏览器崩溃。java

  • C语言是经过手动分配和释放内存的, 如经过malloc分配,经过free释放,这种方式是比较麻烦的。而java、c#、js等是为了解放程序员的负担,提出了程序自动释放内存,这种方式就是垃圾回收机制程序员

JavaScript 中的两种 垃圾回收机制

引用计数

即跟踪记录每一个值被引用的次数,当声明了一个变量并将一个引用类型赋值给该变量时,则这个值的引用次数就是1; 相反,若是包含对这个值引用的变量又取得了另一个值,那么这个值的引用次数就减1;当引用次数变为0的时候,则说明没有办法再访问到这个值了,因此,就能够把其所占用的内存空间给收回来。 这样,垃圾收集器下次再运行时,他就会释放哪些引用次数为0的值所占的内存。编程

DEMO:c#

function test(){

 var a = {} ; //a的引用次数为0

 var b = a ; //a的引用次数加1,为1

 var c =a; //a的引用次数再加1,为2

 var b ={}; //a的引用次数减1,为1

}
复制代码

标记清除

  这是JavaScript中最经常使用的垃圾回收机制。当变量进入环境时,就标记这个变量为“进入环境”,逻辑上说,永远不能释放进入环境的变量所占用的内存,由于一旦进入环境就有可能随时用到他们,当变量离开环境的时候,将其标记为“离开环境”。数组

DEMO:浏览器

function test(){

 var a = 10 ; 
 //被标记 ,进入环境

 var b = 20 ; 
 //被标记 ,进入环境

}

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

何时触发 垃圾回收

ie

垃圾回收器周期性运行,若是分配的内存很是多,那么回收工做也会很艰巨,肯定垃圾回收时间间隔就变成了一个值得思考的问题。IE6的垃圾回收是根据内存分配量运行的,当环境中存在256个变量、4096个对象、64k的字符串任意一种状况的时候就会触发垃圾回收器工做,看起来很科学,不用按一段时间就调用一次,有时候会不必,这样按需调用不是很好吗?可是若是环境中就是有这么多变量等一直存在,如今脚本如此复杂,很正常,那么结果就是垃圾回收器一直在工做,这样浏览器就无法儿玩儿了。编程语言

微软在IE7中作了调整,触发条件再也不是固定的,而是动态修改的,初始值和IE6相同,若是垃圾回收器回收的内存分配量低于程序占用内存的15%,说明大部份内存不可被回收,设的垃圾回收触发条件过于敏感,这时候把临街条件翻倍,若是回收的内存高于85%,说明大部份内存早就该清理了,这时候把触发条件置回。这样就使垃圾回收工做职能了不少函数

合理的 GC 方案

1)、Javascript引擎基础GC方案是(simple GC):mark and sweep(标记清除),即:spa

(1)遍历全部可访问的对象。

(2)回收已不可访问的对象。

相关文章
相关标签/搜索