共计 945 个字符,预计需要花费 3 分钟才能阅读完成。
垃圾回收机制(Garbage Collection)简称GC,是JavaScript中使用的内存管理系统的基本组成部分
JavaScript 是在创建变量(对象、字符串)时自动进行了内存分配,并且在不使用它们时 “自动” 释放的过程称为垃圾回收
内存在不使用的时候会被垃圾回收器自动回收
内存的生命周期
JS环境中分配的内存,一般有以下生命周期:
- 内存分配:当我们声明变量、函数、对象的时候,系统会自动为他们分配内存
- 内存使用:即读写内存,也就是使用变量、函数等
- 内存回收:使用完毕,由垃圾回收自动回收不在使用的内存
简称 GC JavaScript 是在创建变量(对象、字符串等)时自动进行了内存分配,并且在不再使用它们时 “自动” 释放
内存在不使用的时候会被垃圾回收器自动回收
垃圾回收算法
所谓垃圾回收,核心思想就是如何判断内存是否已经不再会被使用了,如果是,就视为垃圾释放掉
引用计数法
IE 采用的引用计数算法,定义 “内存不再使用” 的标准很简单,就是看一个对象是否有指向它的引用
算法:
- 跟踪记录每个值被引用的次数
- 如果这个值被引用了一次,那么就记录次数加 1
- 多次引用会累加
- 如果减少一个引用就减 1
- 如果引用次数是 0,则释放内存(回收掉)
由上面可以看出,引用计数法是个简单有效的算法
但它却存在一个致命的问题:循环引用
如果两个对象相互引用,尽管它们已不再使用,垃圾回收器不会进行回收,导致内存泄漏
function fn() {
let o1 = {}
let o2 = {}
o1.a = o2
o2.a = o1
return '引用计数无法被回收'
}
fn()
因为它们的引用次数永远不会为 0,这样的相互引用如果说很大量的存在就会导致大量的内存泄漏
标记清除法
现代的浏览器已经不再使用引用计数法了
现代浏览器通常用的大多是基于标记清除法的某些改进算法,总体思想都是一致的
核心:
- 标记清除算法将 “不在使用的对象” 定义为 “无法到达的对象”
- 标记:就是从根部(在JS中就是全局对象)出发定时扫描内存中的对象,凡是能从根部到达的对象,都是还需要使用的
- 回收:那些无法由根部出发触及到的对象被标记为不再使用,稍后进行回收
总结
- 引用计数法:看是否有被引用,没有被引用则会回收,但是对于循环引用则没有办法回收
- 标记清除法:核心思路是是否可达的,找所有从根开始引用的对象,做标记,后面回收所有不可达的对象
正文完
发表至: 笔记
2024-05-21