JS中的垃圾回收和性能优化

94 阅读2分钟

性能优化

GC

参考技术文章

引用计数

  1. 介绍
    • 当引用关系发生改变时,修改引用计数
    • 当引用计数为0时,垃圾回收
  2. 优点
    • 发现垃圾立即回收
    • 减少程序暂停
  3. 缺点
    • 无法回收循环引用
    • 需要维护引用计数,时间开销大

标记清除

  1. 介绍
    • 分标记和清除阶段
    • 遍历所有对象找到标记活动对象
  2. 优点
    • 只查找可达对象,可以回收循环引用
  3. 缺点
    • 空间碎片化

标记整理

标记清除的增强,会整理内存地址

V8垃圾回收机制

+ 分代回收(老生代/新生代)
+ 针对不同对象采用不同方法

新生代(存活时间短的)Scavenge

+ 32MB/16MB (x64/x86)
+ 分为From(使用空间)和To(空闲空间) 2个等大的空间
+ 当From空间使用满后,出发标记整理拷贝至To空间,FromTo交换空间
+ 拷贝过程中可能出现晋升,即存储到老生代
    - 一轮GC之后还存活
    - To空间使用率超过25%

老生代

+ 1.4GB/700MB (x64/x86)
+ 标记清除(主要) 标记整理(空间优化) 增量标记(效率优化)

并发标记(GC的优化)

并发标记

Performance

shift+esc 打开应用管理

性能优化最佳实践

jsbench

  1. 慎用全局变量(全局永远是可访问的)
  2. 在原型上添加方法
  3. 避免闭包内存泄漏
  4. 如无必要,避免使用属性访问方法
  5. 循环方式优选
  6. 直接量替换Object
  7. if/else 层级嵌套不易过深
  8. 减少声明及语句数量

闭包的本质

  1. 当函数被外部引用时,由于其标记清除GC是可访问的,所以不会被清除,起执行上下文会被保存下来。
function objGroups(obj1, obj2) {
    //循环引用示例
    obj1.next = obj2;
    obj2.prev = obj1;

    return {
        o1: obj1,
        o2: obj2,
    };
}

let obj = objGroups({name:'obj1'}, {name:'obj2'});