内容概要

  • 内存管理
  • 垃圾回收与常见GC算法
  • V8引擎的垃圾回收
  • Performance工具
  • 代码优化实例


JavaScript 内存管理

内存管理介绍

  • 内存: 由可读写单元组成, 表示一片可操作空间
  • 管理:人为的去操作一片空间的申请、使用和释放
  • 内存管理: 开发者主动申请空间、使用空间、释放空间
  • 管理流程: 申请 - 使用 - 释放
    1. // 申请
    2. let obj = {}
    3. // 使用
    4. obj.name = 'lg'
    5. // 释放
    6. obj = null

javaScript 中的垃圾回收

  • js中的内存管理是自动的
  • 对象不再被引用时的垃圾
  • 对象不能从根上访问到时是垃圾

    javaScript中的可达对象

  • 可以访问到的对象就是可达对象 (引用、作用域链)

  • 可达的标准就是从根出发是否能够被找到
  • javaScript 中的根就可以理解为是全局变量对象

    GC算法介绍

  • GC就是垃圾回收机制的简写

  • GC可以找到内存中的垃圾、并释放和回收空间
  • GC里的垃圾是什么
    • 程序中不再需要使用的对象
    • 程序中不能再访问到的对象
  • GC算法就是工作时查找和回收所遵循的规则
  • 常见GC算法
    • 引用计数
    • 标记清除
    • 标记整理
    • 分代回收

引用计数算法的实现原理

  • 核心思想: 设置引用书,判断当前引用数是都为0
  • 引用计数器
  • 引用关系改变时修改引用数字
  • 引用数字为0时立即回收
  • 引用计数算法优点
    • 发现垃圾时立即回收
    • 最大限度减少程序暂停
  • 引用计数算法缺点

    • 无法回收循环引用的对象
    • 时间开销大 ```typescript function fn() { const obj1 = {} const obj2 = {}

    obj1.name = obj2 obj2.name = obj1

    return ‘dsfdsf’ }

fn() ```

标记清除算法实现原理

  • 核心思想: 分标记和清除二个阶段完成
  • 遍历所有对象找标记活动对象
  • 遍历所有对象清除没有标记对象
  • 回收相应的空间
  • 优点
    • 可以回收循环引用对象
  • 缺点

    • 容易产生碎片化空间、浪费空间
    • 不会立即回收垃圾对象

      标记整理算法实现原理

  • 标记整理可以看作是标记清除的增强

  • 标记阶段的操作和标记清除一致
  • 清除阶段会先执行整理,移动对象位置
  • 优点
    • 减少碎片化空间,弥补标记清除算法的缺点
  • 缺点
    • 不会立即回收垃圾对象

认识V8

  • V8 是一款主流的JavaScript 执行引擎
  • V8采用即时编译
  • V8内存设限 64位 不超过 1.5g 32位 不超过 800m

V8 垃圾回收策略

  • 采用分代回收的思想
  • 内存分为新生代、老生代
  • 针对不同的对象采用不同的算法
  • V8 中常用的GC算法
    • 分代回收
    • 空间复制
    • 标记清除
    • 标记整理
    • 标记增量
  • V8 内存分配

    • V8 内存空间一分为二
    • 小空间用于存储新生代对象(32M | 16M)
    • 新生代指的是存活时间较短的对象

      新生代对象回收实现

  • 回收过程采用复制算法 + 标记整理

  • 新生代内存区分为二个等大小空间
  • 使用空间为From,空闲空间为To
  • 活动对象存储于From空间
  • 标记整理后将活动对象拷贝至To
  • From与To交换空间完成释放
  • 回收细节说明
    • 拷贝过程中可能出现晋升
    • 晋升就是将新生代对象移动至老生代
    • 一轮GC还存活的新生代需要晋升
    • To空间的使用率超过25%

老年代对象回收实现

  • 主要采用标记清除、标记整理、增量标记算法
  • 首先使用标记清除完成垃圾空间的回收
  • 采用标记整理进行空间优化
  • 采用增量标记进行效率优化

为什么使用Performance

  • GC的目的是为了实现内存空间的良性循环
  • 良性循环的基石是合理使用
  • 时刻关注才能确定是否合理
  • Performance 提供多种监控内存方式