js垃圾回收
灵感胜于汗水 Lv5

js垃圾回收机制

  1. 找出不在使用的变量
  2. 释放器内存空间
  3. 固定的时间间隔执行

标记清除

当变量进入执行环境是,就标记这个变量为“进入环境“,进入环境的变量所占用的内存就不能释放。当变量离开环境时,则将其标记为“离开环境“。

被标记为“离开环境”的变量等待垃圾回收。

全局变量和闭包所形成的特殊的变量不会被标记为“离开环境”:

1
2
3
4
5
6
7
8
9
10
11
function f1(){
let a=1
return function f2(){
a++
console.log(a)
}
}

const f3 = f1()
f3() //2
f3() //3

在上述代码中,函数执行完之后变量a并没有消失,因为不会被标记清除,也就是不会被垃圾回收。

解决:

1
f3 = null

引用计数

根据一个值的引用次数来判断是否进行垃圾回收,如果一个值的引用次数是0,就表示这个值不再用到了,因此可以将这块内存释放。

1
2
3
4
5
6
7
8
const a = new Object() //a的引用数:1
const b = new Object() //b的引用数:1

let c = a //a的引用数:2
let c = b //a的引用数:1,b的引用数:2

a.prop = b
b.prop = a //a的引用数:2,b的引用数:2

如上所示,a和b的引用数永远都大于0,不会被垃圾回收。所以使用引用计数来进行垃圾回收的浏览器较少。

解决:(解除引用)

1
2
a = null
b = null

V8引擎垃圾回收

V8是一个由Google开源的采用C++编写的高性能JavaScript和WebAssembly引擎,应用在 Chrome和Node.js等。

在 V8 中会把堆分为新生代和老生代两个区域,新生代中存放的是生存时间短的对象(大部分对象),老生代中存放的生存时间久的对象(比如Vue)。

新生代的内存空间小(16/32M),老生代的内存空间大(0.7/1.4G)

新生代的对象被使用很多次之后会被转移到老生代中,老生代使用的垃圾回收机制就是标记清除。

新生代的垃圾回收机制是ScavengeScavenge又是基于cheney算法的:

cheney算法将内存分为from和to两个区域(各一半),正在使用的对象都存在from中,假如有一个对象被赋值为null(等待垃圾回收)

  • 将需要被回收的对象留在from中,其他数据转移到to中
  • 将from和to中的所有数据互换
  • 将to中的数据回收

cheney算法用空间换取时间(有一半内存不能用)

参考视频

  • 本文标题:js垃圾回收
  • 本文作者:灵感胜于汗水
  • 创建时间:2022-04-06 16:06:58
  • 本文链接:https://cjhsyc.github.io/2022/04/06/js垃圾回收/
  • 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!