垃圾回收机制
Opened this issue · 0 comments
lzlu commented
JavaScript高级程序设计
- 标记清除
- 最常用的垃圾收集方式(mark and sweep)
- 标记变量的方式:翻转某个特殊的位,使用“进入环境”变量列表和“离开环境”变量列表。
- 执行策略:标记所有变量—> 去掉环境中的变量以及被环境中变量引用的变量—>这时候被标记的变量将被视为准备删除的变量 —>内存清除,销毁带标记的变量并回收它们所占用的内存空间
- 引用计数
- 跟踪记录每个值被引用的次数。
- 存在的严重的问题:循环引用。(A->B,B->A,这两个对象的引用次数永远不等于0。)
- 影响:IE9以下版本,BOM和DOM对象是C++以COM对象的形式实现的,COM对象的垃圾回收机制采用的是引用计数策略。需要手动断开原生JS对象与DOM原生之间的链接(设置值为null)
- 性能问题
- IE7之前的垃圾收集器是根据内存分配量运行的(256个变量,4096个对象(或数组)字面量和数组元素或者64kb的字符串。
- IE7之后工作方式:触发垃圾收集的变量分配,字面量和数组元素的临界值被调整为动态修正。
- 管理内存
- 解除引用(设值为null):让值脱离执行环境,以便垃圾收集器下次运行时将其回收。
V8垃圾回收机制
V8垃圾回收机制
V8采用了一个分代(Generational)垃圾回收器,将内存堆分割为新生代(Young Generation)和老龄代(Old Generation)。针对这两种在其内部使用不同的垃圾回收算法
- 内存堆内存分配—分代算法
- 新生代内保存的是最新创建且存活周期短的对象。老龄代内保存的是较为活跃且存活周期长的对象。
- 复制算法(新生代内存)
- 将内存一分为二(semispace),一半在使用中(From空间),一半空闲(To空间)。
- 垃圾回收开始时,检查From空间中的存活对象,这些存活对象将被复制到To空间中,而非存活对象占用的空间将被释放。
- 完成复制后,From空间和To空间的角色发生互换,From空间变为To空间,To空间变为From空间。
- 牺牲空间换取时间。适合新生代内存(周期短)
- 新生代晋升老龄代条件:1.对象是否经历过复制算法回收。2.To空间的内存占用比超过一定的限制。
- 标记—清除算法(老龄代内存) * 在标记阶段遍历堆中的所有对象,并标记活着的对象,在随后的清除阶段中,只清除没有被标记的对象。 * 内存空间不连续问题
- 标记—合并算法(老龄代内存) * 在整理的过程中,将活着的对象往一端移动,在移动完成后,直接清理掉另一端死亡的对象。
- 总结 * 复制算法只复制活着的对象,而标记-清除算法只清理死亡的对象。这是因为活对象在新生代中占较小部分,死对象在老龄代中占较小部分,这也是两种回收方式能高效工作的原因。
#前端/JavaScript#