js-垃圾回收
垃圾回收
JavaScript 中的内存管理是自动执行的,而且是不可见的。
由于字符串,对象和数组没有固定大小,所有当他们的大小已知时,才能对他们进行动态的存储分配。JavaScript 程序每次创建字符串、数组或对象时,解释器必须分配内存来存储那个实体。只要像这样动态地分配了内存,最终都要释放这些内存以便他们能够再用,否则,JavaScript 的解释器将会消耗完系统中所有可用内存,造成系统崩溃
JavaScript 垃圾回收很简单:找到不再使用的变量,然后释放掉其占用的内存。但是这个过程不是实时的,因为开销比较大,所以垃圾回收器会按照固定的时间间隔周期性执行。
内部算法
标记清除
基本的垃圾回收算法称为 “标记-清除“,定期执行以下 “垃圾回收” 步骤
垃圾回收器获取根并 “标记“ 他们
然后它访问并 标记 所有来自他们的引用
然后它访问标记的对象并标记他们的引用(所有被访问的对象都被记住,以便以后不再访问同一对象两次)
以此类推,直到有未访问的引用(可以从根访问)为止
除标记的对象外,所有对象都被删除
垃圾回收器只在 CPU 空闲时运行,以减少对执行的可能影响
引用计数
在 JavaScript 引擎中有一个引用表,保存着内存里面所有的资源的引用次数。如果一个值的引用次数是 0,就表示这个值不再用到了,因此就可以将这块内存释放掉
如果一个值不再需要了,引用数却不为 0,垃圾回收机制无法释放这块内存,从而导致内存泄漏
要解决循环引用的问题,最好在不使用他们的时候手工将他们设置为空
哪些情况会引起内存泄漏
意外的全局变量
未被声明的变量会变成一个全局变量,在页面关闭之前不会被释放。
被遗忘的计时器或回调函数
闭包
闭包可以维持函数内部的变量,使其得不到释放。
解决:将事件处理函数定义在外部,解除闭包,或者在定义事件处理函数的外部函数中,删除对 dom 的引用
垃圾回收优化
数组优化
在清空一个数组项的时候优先使用.length = 0
的方式去清空数组,如果使用 =[]
的方式会将原来的数组对象变成一个内存垃圾
对象尽量复用
对象尽量复用,不用的对象尽可能设置为 null
最后更新于