js垃圾回收和内存泄漏
js垃圾回收
Js具有自动垃圾回收机制。垃圾收集器会按照固定的时间间隔周期性的执行。
1.标记清除(常用)
工作原理:是当变量进入环境时,将这个变量标记为“进入环境”。当变量离开环境时,则将其标记为“离开环境”。标记“离开环境”的就回收内存。
工作流程:
1.垃圾回收器在运行的时候会给存储在内存中的所有变量都加上标记。
2.去掉环境中的变量以及被环境中的变量引用的变量的标记(闭包)。
3.依然被标记的会被视为准备删除的变量。
4.垃圾回收器完成内存清除工作,销毁那些带标记的值并回收他们所占用的内存空间。
2.引用计数
跟踪记录每个值被引用的次数
工作流程:
1.声明了一个变量并将一个引用类型的值赋值给这个变量,这个引用类型值的引用次就是1。
2.同一个值又被赋值给另一个变量,这个引用类型值的引用次数加1.
3.当包含这个引用类型值的变量又被赋值成另一个值了,那么这个引用类型值的引用次数减1.
4.当引用次数变成0时,说明没办法访问这个值了。
5.当垃圾收集器下一次运行时,它就会释放引用次数是0的值所占的内存。
内存泄漏
使用了内存之后, 如果后面他们不会再被用到,但是还没有及时释放,这就叫做内存泄露(memory leak)。如果出现了内存泄露,那么有可能使得内存越来越大,而导致浏览器崩溃。
引起内存泄漏的情况:
- 意外的全局变量引起的内存泄漏。
function foo(arg) {
bar = "this is a hidden global variable"; // 没有用var
}
function foo() {
this.variable = "potential accidental global";
}
// 一般函数调用,this指向全局
原因:全局变量,不会被回收。
解决:使用严格模式避免,函数内使用var定义,块内使用let、const。
2. 闭包引起的内存泄漏
原因:闭包可以维持函数内局部变量,使其得不到释放。
解决:将事件处理函数定义在外部,解除闭包,或者在定义事件处理函数的外部函数中,删除对dom的引用。