垃圾回收机制
- 概念
来处理程序运行中产生的垃圾,没有引用的对象等
- 在JS中拥有自动的垃圾回收机制,会自动将这些垃圾对象从内存中销毁,我们不需要也不能进行垃圾回收的操作。
- 我们需要做的只是要将不再使用的对象设置为null 即可。
内部算法
基本的垃圾回收算法称为“标记-清除”,定期执行以下“垃圾回收”步骤:
- 垃圾回收器获取根并“标记”(记住)它们。
- 然后它访问并“标记”所有来自它们的引用。
- 然后它访问标记的对象并标记它们的引用。所有被访问的对象都被记住,以便以后不再访问同一个对象两次。
- 以此类推,直到有未访问的引用(可以从根访问)为止。
- 除标记的对象外,所有对象都被删除。
什么是垃圾
- 一般来说没有被引用的对象就是垃圾,就是要被清除, 有个例外如果几个对象引用形成一个环,互相引用,但根访问不到它们,这几个对象也是垃圾,也要被清除。
内存泄漏
内存泄漏(Memory Leak)是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。
常见的内存泄露
作用域未释放(闭包)
var leakArray = []; exports.leak = function () { leakArray.push("leak" + Math.random()); }
每次调用 leak 方法,都会导致局部变量 leakArray 不停增加且不被释放。
闭包可以维持函数内部变量驻留内存,使其得不到释放
没必要的全局变量
声明过多的全局变量,会导致变量常驻内存,要直到进程结束才能够释放内存。
无效的 DOM 引用
定时器未清除
内存泄漏优化
1.解除引用
在执行中的代码只保存必要的数据。一旦数据不再有用,通过将其值设置为 null 来释放其引用——这个做法叫做解除引用(dereferencing)
解除一个值的引用并不意味着自动回收该值所占用的内存。解除引用的真正作用是让值脱离执行环境,以便垃圾收集器下次运行时将其回收
- 提供手动清空变量的方法
- 在业务不需要用到的内部函数,可以重构在函数外,实现解除闭包
- 避免创建过多生命周期较长的对象,或将对象分解成多个子对象
- 避免过多使用闭包
- 注意清除定时器和事件监听器