内存
管理
管理流程
申请内存空间
let obj = {};
使用内存空间
obj.name = 'xx';
释放内存空间
obj = null;
垃圾
JavaScript 中内存管理是自动的
对象不再被引用时是垃圾
- 对象不能从根上访问到时是垃圾
可达对象
- 可以访问到的对象就是可达对象(引用、作用域链)
- 可达的标准就是从根出嫁是否能够被找到
- JavaScript 中的根就是可以理解为是全局变量对象(全局执行上下文)
let obj = { name: 'xm' }; let ali = obj; obj = null;
- obj 指向 { name: ‘xm’ } 的地址
- ali 指向 { name: ‘xm’ } 的地址
- obj 指为 null 空指针
但通过 ali 还是能访问到 { name: ‘xm’ } 的地址。所以 { name: ‘xm’ } 还是可达对象
function objGroup(obj1, obj2) {
obj1.next = obj2;
obj2.prev = obj1;
return {
o1: obj1,
o2: obj2
}
}
把 o1 通过 delete o1;
删除
把所有通往 o1 的连接都删除了,那么这部份就认为是垃圾。最终其空间会被 JavaScript 引擎所回收
常见 GC 算法
引用计数
- 核心思想: 设置引用数,判断当前引用数是否为 0
- 引用计数器
- 引用关系改变时修改引用数字
- 引用数字为 0 时立即回收
优点
- 发现垃圾时立即回收
- 最大限度减少程序暂停
缺点
- 无法回收循环引用的对象
-
循环引用对象
```javascript function fn(){ const obj1 = {}; const obj2 = {};
obj1.name = obj2; // 相互指针引用, 在引用计数中无法解决 obj2.name = obj1; }
标记清除
- 核心思想: 分标记和清除两个阶段完成
- 遍历所有对象找标记活动对象
- 遍历所有对象清除没有标记对象
- 回收相应空间
优点
- 可以解决对象循环引用问题
缺点
- 回收时的地址不一定连续,会造成空间的碎片化,浪费空间
- 不会阙发回收垃圾对象
标记整理
- 标记清除的增强,以减少碎片化空间
- 标记阶段的操作和标记清除一致
- 清除阶段会先执行整理,移动活动对象移动到一侧的位置,再把活动对象的另一则进行空间回收
分代回收
V8 引擎