js性能优化学习笔记1-内存管理和垃圾回收

168 阅读3分钟

内存管理

  • js中的内存管理是自动的,对象不再被引用或者不能从根上访问到时视为垃圾。
  • 可达对象:从根(js中的根可以理解为全局变量对象)出发可以被找到的对象。
// 内存管理分为申请、使用、释放内存空间
// 申请
let obj = {}
// 使用
obj.name = 'lily'
// 释放
obj = null

垃圾回收和常见的GC算法

  • GC(垃圾回收机制):可以找到内存中的垃圾(程序中不再需要使用或不能再访问到的对象)、并释放和回收空间。
  • 常见的GC算法:引用计数、标记清除、标记整理、分代回收

引用计数

  • 核心思想: 设置引用数,判断当前引用数是否为0。当引用关系改变时,引用计数器会修改引用数字,引用数字为0时立即回收。
  • 优点:可以立即回收垃圾对象。
  • 缺点:无法回收循环引用的对象。时间开销大。

标记清除

  • 核心思想: 遍历所有对象并标记活动对象,再遍历所有对象清除没有标记的对象
  • 缺点:要清除的几个对象如果内存空间地址不连续,清除后会导致空间碎片化。不能立即回收垃圾对象。

标记整理

  • 核心思想: 标记清除的增强版,标记之后,在清除时会先执行整理,移动活动对象位置使其在地址上产生连续

V8引擎的垃圾回收

V8: 主流的 js 执行引擎,采用即时编译,内存设限(64位1.5G,32位800M)

  • 基础类型数据都是由语言本身来控制的,所以回收策略是针对于活在堆内存中的对象数据。
  • V8 中常用的 GC 算法:分代回收、空间复制、标记清除、标记整理、标记增量

分代回收

  • V8将内存空间一分为二,分为新生代和老生代存储区
  • 小空间(64位32M|32位16M)用于存储新生代对象( 指存活时间较短的对象,比如局部作用域中的对象 )
  • 大空间(64位1.4G|32位700M)用于存储老生代对象( 指存活时间较长的对象,比如全局作用域中或者闭包中的对象 )

新生代回收

空间复制 + 标记整理:空间换时间

  1. 新生代内存区也分为两个等大的空间:From(使用空间), To(空闲空间)
  2. 活动对象都存储在 From 空间,触发GC机制时,会进行标记整理
  3. 在标记整理的过程中可能会出现晋升,就是将新生代对象移动到老生代:
    • 一轮 GC 还存活的新生代需要晋升
    • To 空间的使用率超过 25%
  4. 标记整理之后将活动对象拷贝到 To 空间
  5. 交换 From 和 To 空间,完成 From 空间的释放

老生代回收

标记清除 + 标记整理 + 标记增量

  1. 使用标记清除完成垃圾空间的回收
  2. 当发生晋升,发现老生代空间不足以存储移过来的新生代对象时,采用标记整理进行空间优化
  3. 采用标记增量进行效率优化:垃圾回收会阻塞当前程序的执行,标记增量就是将标记过程分段执行,使得垃圾回收可以和当前程序交替进行,用户体验更好

学习自拉钩教育前端视频