垃圾回收
上一题聊到了闭包,大家都知道,闭包会维持函数内部的变量,使得其不能被释放。这可能会造成内存泄露。所以现在我们来了解一下js的垃圾回收机制。
原理大箩筐
由于字符串、对象和数组没有固定的大小。需要当它们的大小已知时,才能对它们进行动态的储存分配。JAVASCRIPT每次创建字符串、对象和数组时,解释器都必须分配内存来储存这些实体。只要像这样动态地分配了内存,最终都要释放这些内存以便他们能够被再用,否则,JavaScript的解释器将会消耗完系统中所有可用的内存,造成系统崩溃。
上面解释了JS为何需要垃圾回收。JavaScript的解释器可以检测到何时程序不再使用一个对象了,当他确定了一个对象是无用的时候,他就知道不再需要这个对象,可以把它所占用的内存释放掉了。例如:
var a = "before";
var b = "override a";
var a = b; //重写a
这段代码运行之后,“before”这个字符串失去了引用(之前是被a引用),系统检测到这个事实之后,就会释放该字符串的存储空间以便这些空间可以被再利用。
JS最常用的垃圾回收方式是##标记清除##
工作原理:是当变量进入环境时,将这个变量标记为"进入环境"。当变量离开环境时,则将其标记为"离开环境"。标记"离开环境"的就回收内存。
工作流程
- 所有变量加上标记
- 去掉环境中的变量以及被环境中的变量引用的变量的标记。
- 再被加上标记的会被视为准备删除的变量。
- 垃圾回收器完成内存清除工作,销毁那些带标记的值并回收他们所占用的内存空间。
造成内存泄露
- 全局变量:不会被回收
- 闭包引起:闭包维持函数内部的变量,不得释放
- 没有清理dom元素引起
- 定时器或者回调
- 子元素存在一起内存泄露