一、前言
一直有打算总结一下JS内存泄露的方面的知识的想法,但是总是懒得提笔。
富兰克林曾经说过:懒惰,像生鏽一样,比操劳更能消耗身体,经常用的钥匙总是亮闪闪的。安利一下,先起个头。
二、内存声明周期
1、分配内存— 内存是被操作系统分配,这允许程序使用它。在低级语言中(例如C),这是一个作为开发者需要处理的显式操作。在高级语言中,然而,这些操作都代替开发者进行了处理。
2、使用内存。实际使用之前分配的内存,通过在代码操作变量对内在进行读和写。
3、释放内存 。不用的时候,就可以释放内存,以便重新分配。与分配内存操作一样,释放内存在低级语言中也需要显式操作。
三、JS垃圾回收机制及常见方法
JS会在创建变量(对象、字符串)时自动分配内存,并在这些变量不被使用时自动释放内存,这个过程被称为垃圾回收。
3.1、内存引用,包括显示引用和隐式引用;
3.2、引用计数;
语言引擎有一张"引用表",保存了内存里面所有的资源(通常是各种值)的引用次数。如果一个值的引用次数是0
,就表示这个值不再用到了,因此可以将这块内存释放。
3.3、标记清除算法;
四、内存泄露以及常见处理方法
内存泄漏基本上就是不再被应用需要的内存,由于某种原因,没有被归还给操作系统或者进入可用内存池。
对于持续运行的服务进程(daemon),必须及时释放不再用到的内存。否则,内存占用越来越高,轻则影响系统性能,重则导致进程崩溃。
4.1、全局变量
这是常见的,但是js会对未声明的变量的引用在全局对象里创建一个新的变量。不过如果过多,这会带来隐患;
可以开启‘use strict’严格模式,解析JavaScript来阻止意外的全局变量。
4.2、闭包
一个内部函数使用了外部(封闭)函数的变量。能不用就不用吧。
4.3、没有清空的定时器
使用setInterval等定时器会产生很多时间序列,如果不定时回收,就会积累很多。开进行下一个定时器时候把前一个定时器时间序列设置为null;
4.4、DOM的外引用