乐趣区

关于垃圾回收机制:浏览器垃圾回收

垃圾回收算法(v8)

可达性 : 从根节点登程,遍历所有的对象,能够遍历到的对象,就是 可达的

根节点蕴含:

  1. 全局变量window
  2. 文档 DOM
  3. 寄存在栈上的变量

let dog.a = new Array(1)


如果此时,将另外一个对象赋给 a

dog.a = new Object()


那么从根节点 栈 dog一步一步遍历,发现 堆 Array 不可达的,那么它就要被回收掉。

此时会引出一个概念:内存碎片
内存碎片就是不可达的对象被回收后,内存中会存在大量的不间断空间

还有一个问题:浏览器在进行垃圾回收的时候,会暂停 JS 脚本,可能会导致页面卡顿
所以新引擎对其进行了优化

分代收集

浏览器将数据分为两种:短暂对象 长期对象
生命周期很长的对象,比方全局的 window/DOM 等属于短暂对象
存活工夫短,比方函数外部变量,块级作用域变量等属于长期对象
与之对应的垃圾回收器别离是 主垃圾回收器 副垃圾回收器

主垃圾回收器

使用优化版 可达性 回收算法 标记 - 革除 ,在遍历过程中, 可达的 对象进行标记,那么最初没有标记的就判断为垃圾数据。

标记:一个对象拜访一次

屡次回收也会呈现 内存碎片 ,须要进行 内存整理

副垃圾回收器

负责长期对象的垃圾回收,通常只反对 1~8M 的容量
分为两个区域: 对象区域 闲暇区域
新退出的对象都被放入对象区域,等对象区域快满的时候,会执行一次垃圾清理
清理过程:

  • 先给对象区域所有对象进行标记
  • 把标记的可达的对象复制到闲暇区域,并且将它们有序的排列一边
  • 对象区域与闲暇区域对调

在这个模式下,就不会呈现内存碎片问题

增量回收

为了解决优化过程中页面提早问题的优化
将垃圾回收工作分成更小的块,每次解决一部分,屡次解决,这样就会防止长时间的进展

闲时收集

也是一种优化,垃圾收集器只会在 CPU 闲暇时尝试运行,以缩小可能对代码执行的影响

内存透露

用不到的变量,不能被垃圾回收机制回收,仍然占据着内存空间
常见场景:

  • 监听在 window/body 事件没有解绑
  • Vue 中的 $storewatch 之后没有unwatch
  • 相互援用
  • 定时器
  • 滥用闭包

优化:

  • 弱援用weakMap/weakset
  • 数组复用:arr.length = 0
  • 对象复用:t = null

weakMap 和 weakset

弱援用,特点:不能确保其援用的对象不会被垃圾回收器回收

var obj1 = new Object() // 强援用
var obj2 = new WeakMap() // 弱援用

如果两个对象什么都不做,那么 obj2 就会被回收掉,而 obj1 要设置 obj1=null 才会被回收

退出移动版