js垃圾回收机制
一、基本概念
1.内存管理
- 内存: 由可读写单元组成, 表示一片可操作空间
- 管理: 人为的去操作一片空间的申请, 使用和释放
- 内存管理: 开发者主动申请空间, 使用空间, 释放空间
- 管理流程: 申请-使用-释放
2.垃圾回收
- JavaScript中内存管理是自动的
- 对象不再被引用时是垃圾
- 对象不能从根上访问到时是垃圾
3.可达对象
- 可以访问到的对象就是可达对象 (引用, 作用域链)
- 可达的标准就是从根出发是否能够被找到
- JavaScript 中的根就可以理解为是全局变量对象
4.GC定义与作用
- GC就是垃圾回收机制的简写
- GC可以找到内存中的垃圾, 并释放和回收空间
- GC里的垃圾是什么:
- 程序中不再需要使用的对象
- 程序中不能再访问到的对象
- GC算法是什么
- GC是一种机制, 垃圾回收器完成具体的工作
- 工作的内容就是查找垃圾释放空间, 回收空间
- 算法就是工作时查找和回收所遵循的规则
- 常见 GC 算法
- 引用计数
- 标记清除
- 标记整理
- 分代回收
5.引用计数算法
- 核心思想: 设置引用数, 判断当前引用数是否为0
- 计数器
- 引用关系改变时修改引用数字
- 引用数字为0时立即回收
- 优点
- 发现垃圾时立即回收
- 最大限度减少程序暂停 (防止内存暂满)
- 缺点
- 无法回收循环引用的对象
- 时间/资源开销大 (需要维护数值的变化,时刻监控当前对象的数值是否需要修改, 本来对象引用数值的修改就需要时间, 如果有更多的对象需要修改, 时间开销就更大)
6.标记清除算法实现原理
- 核心思想: 分标记和清除两个阶段完成
- 遍历所有对象找标记活动对象
- 遍历所有对象清除没有标记对象
- 回收相应的空间
- 优点:
- 可以解决对象循环引用的问题 (函数调用之后, 内部成员在全局不可访问,所以未做标记)
- 缺点
- 空间碎片化: 回收的垃圾对象在地址上是不连续的, 回收之后分散在各个角落, 后续想要使用的时候, 新的空间匹配就能用, 多了或者少了就不太适合使用了
- 不会立即回收垃圾对象
- 清除时程序是停止工作的
7.标记整理算法实现原理
- 标记整理可以看做是标记清除的增强
- 标记阶段的操作和标记清除一致
- 清除阶段会先执行整理, 移动对象位置, 让他们在地址上产生连续
- 优点
- 减少碎片化空间
- 缺点
- 不会立即回收垃圾对象
8.V8
- V8是一款主流的JavaScript执行引擎
- V8采用即时编译
- V8内存设限(32位不超过800m, 64位不超过1.5g)
V8垃圾回收策略
- 采用分代回收的思想
- 内存分为新生代, 老生代
- 针对不同对象采用不同算法
- V8中常用的GC算法
- 分代回收
- 空间复制
- 标记清除
- 标记整理
- 标记增量
- V8如何回收新生代对象
- V8内存空间一分为二
- 小空间用于存储新生代对象 (32M|16M)
- 新生代指的是存活时间较短的对象
- 新生代对象实现回收
- 回收过程采用复制算法 + 标记整理
- 新生代内存区分为两个等大小的空间
- 使用空间为 From, 空闲空间为 To
- 活动对象存储于 From 空间
- 标记整理后将活动对象拷贝至 To
- From释放之后 与 To 交换空间完成释放
- 回收细节说明
- 拷贝过程中可能出现晋升
- 晋升就是将新生代对象移动至老生代进行存储
- 一轮GC之后还存活的新生代需要晋升
- 拷贝过程中发现 To 空间的使用率超过 25%
- V8如何回收老生代对象
- 老年对象存放在右侧老生代区域
- 64位操作系统1.4G, 32位操作系统700M
- 老年带对象就是指存活时间较长的对象(全局, 闭包...)
- 老年代对象回收实现
- 主要采用标记清除, 标记整理, 增量标记算法 (mark-compact)
- 首先使用标记清除完成垃圾空间的回收
- 采用标记整理进行空间优化
- 当新生代区域往老生代晋升, 老生代空间不足以存放需要移过来的对象
- 采用增量标记进行效率提升
- 细节对比
- 新生代区域垃圾回收使用空间换时间(复制算法)
- 每时每刻都会有一个空闲空间, 但是由于本来空间就很小, 这一部分空闲空间的浪费相对于时间上的提升来说是微不足道的
- 老生代区域垃圾回收不适合复制算法
- 标记增量如何优化垃圾回收
- 将一整段垃圾回收操作拆分成多个小步组合着去完成当前整个回收, 从而去替代之前一口气做完的垃圾回收操作, 实现垃圾回收与程序执行交替完成, 时间消耗更加合理
- 比如说, 程序执行一轮之后, 执行GC遍历对象, 对直接可达对象进行标记. 然后继续执行代码, 然后继续对间接可达对象进项标记, 如此循环, 直到触发GC回收机制之后完成清除, 如此反复循环 (整个V8最大的垃圾回收达到1.5G采用非增量标记形式进行垃圾回收时间也不超过1s)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
2021-04-22 前端框架面学习笔记(三)