目录
1、标记清理
标记清理是 js 中最常用的垃圾回收策略:当变量进入上下文,如在函数中声明一个变量时,这个变量会被加上存在于上下文中的标记。当变量离开上下文时,也会被加上离开上下文的标记。
垃圾回收程序运行的时候:
- 首先会标记内存中的所有变量;
- 然后将①还在上下文中的、②被在上下文中的变量引用的变量的标记去掉,最后还有标记的变量就是待删除的。因为其即不在上下文中,也没有被在上下文中的变量引用。
- 随后垃圾回收程序清理掉所有带有标记的变量。
但标记清理有一个问题:其清理完后,内存中的空间是不连续的,存在内存碎片。当后续需要非常大的空间时,并不能将这些碎片连续起来给到这个大空间,若剩余空间不够,则不能满足需求。
标记整理方法可以有效地解决这个问题。标记阶段没有什么不同,只是标记结束后,标记整理方法会将活着的对象向内存的一边移动,最后清理掉边界的内存。
但标记整理方法效率不如标记清理方法。
js 中的垃圾
(1)全局变量:在全局作用域中声明的变量不是垃圾,因为程序不知道你何时将会用到它,可能你现在用不到,但是在几百上千行代码或更多后用到。
(2)局部变量:局部变量在函数退出后,就变成了垃圾。
function f() {
let a = 1;
return a; // 在 return 后,a 就变成了垃圾
}
(3)单引用
let a = 1;
let a = null;
当定义变量 a 时,内存开辟一点空间存放 1 ,但是当我们将 a 赋值为 null 后,此前为它开辟的空间就没有作用了,即变成了垃圾。
(4)双引用
let person = {
name: '张三'
};
let user = person;
当定义变量 person 时,给其开辟空间存储 '张三' ,此后又定义 user 指向为 person 开辟的空间,此时需将 person 和 user 全部去除才能将这个开辟的空间清理掉。
(5)环引用
function mar