Javascript 性能优化01
2021-05-22 本文已影响0人
丽__
主要内容:
- 内存管理
- 拉勾回收与常见GC算法
- V8引擎的垃圾回收
- Performance工具
- 代码优化实例
一、内存管理
- 内存:由可读写单元组成,表示一片可操作空间
- 管理:人为的去操作一片空间的申请、使用和释放
- 内存管理:开发者主动申请空间、使用空间、释放空间
- 管理流程:申请 - 使用 - 释放
//申请
let obj = {}
//使用
obj.name = 'zhangsan'
//释放
obj = null
二、JavaScript中的垃圾回收
- JavaScript中内存管理是自动的
- 对象不再被引用时是垃圾
- 对象不能从根上访问到时是垃圾
Javascript中的可达对象
- 可以访问到的对象就是可达对象(引用、作用域链)
- 可达的标准就是从根出发是否能够被找到
- JavaScript中的根就可以理解为是全局变量对象
JavaScript中的引用与可达是怎样体现的
function objGroup(obj1,obj2){
obj1.next = obj2
obj2.prev = obj1
return {
o1:obj1,
o2:obj2
}
}
let obj = objGroup({name:'obj1'},{name:'obj2'})
image.png
三、GC算法介绍
- GC就是垃圾回收机制的简写
- GC可以找到内存中的垃圾、并释放和回收空间
GC垃圾是什么
- 程序中不再需要使用的对象
- 程序中不能再访问到的对象
GC算法是什么
- GC是一种机制,垃圾回收器完成具体的工作
- 工作的内容就是查找垃圾释放空间、回收空间
- 算法就是工作时查找和回收所遵循的原则
常见的GC算法
- 引用计数
- 标记清除
- 标记整理
- 分代回收
四、引用计数算法实现原理
- 核心思想:设置引用数,判断当前引用数是否为0
- 引用计数器
- 引用关系改变时修改引用数字
- 引用数字为0时立即回收
五、引用计数算法优缺点
优点:
- 发现垃圾时候立即回收
- 最大限度减少程序暂停
缺点 - 无法回收循环引用的对象
- 时间开销大
function fn(){
const obj1 = {}
const obj2 = {}
obj1.name = obj2;
obj2.name = obj1;
//循环引用的对象无法进行回收
return '456465465'
}
fn()
六、标记清除算法实现原理
- 核心思想:分为标记和清除二个阶段完成
- 遍历所有对象找到标记活动的对象
- 遍历所有对象清除没有标记的对象
-
回收相应的空间
image.png
七、标记清除算法优缺点
优点:可以回收循环引用的对象,可以解决/循环引用的对象无法进行回收的问题
缺点:容易产生碎片化空间,浪费空间。相对于之前的垃圾回收来说,会产生空间碎片化的问题,不能让空间得到最大化的使用
不会立即回收垃圾对象
八、标记整理算法实现原理
- 可以看做标记清除算法的增强
- 标记阶段的操作和标记清楚一致
- 清除阶段会先执行整理,移动对象位置
标记整理的优缺点
优点:减少碎片化空间
缺点:不能立即回收垃圾对象
十、认识V8
- V8是一款主流的JavaScript执行引擎
- V8 采用即时编译,速度快
- V8内存设限,64位操作系统下不超过1.5G,32位操作系统下不超过800M
十一、V8 垃圾回收策略
- 采用分代回收的思想
- 内存分为新生代存储区、老生代存储区
- 针对不同对象采用不同算法
v8中常用的GC算法
- 分代回收
- 空间复制
- 标记清除
- 标记整理
- 标记增量
十二、V8如何回收新生代对象
V8内存分配
- V8内存一分为2
- 小空间存储新生代对象(32M | 16M)
- 新生代指的是存活时间较短的对象
新生代对象回收实现
- 回收过程采用复制算法 + 标记整理
- 新生代内存区分为两个等大小空间
- 使用空间为From,空闲空间为To
- 活动对象存储于From空间
- 标记整理后将活动对象拷贝至To
回收细节说明
- 拷贝过程中可能出现晋升
- 晋升就是将新生代对象移动至老生代
- 一轮GC还存活的新生代需要晋升
- To空间的使用率超过25%也需要晋升
十三、V8 如何回收老生代对象
- 老生代对象存放在右侧老生代区域
- 64位操作系统中国1.4G,32位操作系统中700M
- 老生代对象指的就是存活时间较长的对象
老生代对象回收实现
- 主要采用标记清除算、标记整理、增量标记算法
- 首先使用标记清楚完成垃圾空间的回收
- 采用标记整理进行空间优化
- 采用增量标记进行效率优化
细节对比
- 新生代区域垃圾回收使用空间换时间
- 老生代区域垃圾回收不适合复制算法
十四、Performance工具介绍
- GC的目的就是为了实现内存空间的良性循环
- 良性循环的基石是合理使用
- 时刻关注才能确定是否合理
- Performance提供多种监控方式
Performance使用步骤
- 打开浏览器输入目标网址
- 进入开发人员面板,选择性能
- 开启录制功能,访问具体界面
- 执行用户行为,一段时间后停止录制
- 分析界面中记录的内存信息
十五、内存问题的外在表现
- 页面出现延迟加载或者经常性暂停
- 页面持续性出现糟糕性能
- 页面的性能随着时间的延长越来越差
十六、监控内存的几种方式
界定内存问题的标准
- 内存泄漏:内存使用持续升高
- 内存膨胀:在多数设备上都存在性能问题
- 频繁垃圾回收:通过内存变化图进行分析
监控内存的几种方式
- 浏览器任务管理器 shift + Esc
- Timeline时序图记录
- 堆快照查找分离DOM
- 判断是否存在频繁的垃圾回收
十七、任务管理器监控内存
浏览器任务管理器 shift + Esc
image.png
十八、Timeliness记录内存
image.png十九、堆快照查找分离DOM
什么是分离DOM
- 界面元素存活在DOM树上
- 垃圾对象时的DOM节点
- 分离状态的DOM节点
F12 --> 内存-->堆快照
二十、判断是否存在频繁的GC
为什么确定频繁垃圾回收
- GC工作时应用程序是停止的
- 频繁且过长的GC会导致应用假死
- 用户使用中感知应用卡顿
确定频繁的垃圾回收
- Timeline中的频繁的上升下降
- 任务管理器中数据频繁增加减小