JS 引擎有一个后台垃圾回收进程, 按照可访问性判断是否是垃圾数据, 具体流程:
- 是会从 GC Root 节点出发访问对象, 不能抵达的为垃圾数据,并标记
- 统一清理垃圾数据
- 内存整理, 内存整理又有进一步设计, 根据两个假说:
- 大部分对象都是存活周期短暂
- 不死的对象会活的更久
- 所以将堆空间分为和老生代和新生代空间
新生代空间
新生代用副垃圾回收期
- 新对象存入新生区
- 然后新生区分成存储区和空闲区
- 垃圾回收时会把被标记为有效的数据, 从存储区复制到空闲区
- 然后反转空闲区和存储区
老生代空间
两次新生代标记后依旧存在的数据, 会转到老生代, 老生代采用主垃圾回收器是采用 标记 - 清除(Mark-Sweep)
- 首先是标记过程阶段。标记阶段就是从一组根元素开始,递归遍历这组根元素,在这个遍历过程中,能到达的元素称为活动对象,没有到达的元素就可以判断为垃圾数据。
- 直接清理
- 但次数多了会有碎片空间, 然后标记-整理, 将对象移动到一端.
进一步优化
- 增量回收: 将回收任务分片
- 后台回收: 将标记对象、移动对象等任务转移到后台线程进行, 并引入了辅助线程, 并行回收
- 三色标记法