1.2.3 - JavaScript 性能优化(垃圾回收-上)

267 阅读5分钟

内存管理

垃圾回收与常见GC算法

V8引擎的垃圾回收

performance工具

优化代码实例

★ 内存管理

垃圾回收

找到垃圾,让js执行引擎回收,去根上找,没有用到的就是垃圾,就要给他回收,找的这个过程用到了可达对象引用

可达对象

  • 可以访问到的对象就是可达对象
  • 标准是从根上出发
  • js中根就是全局变量对象,全局执行上下文

引用数值变化


★ GC算法【垃圾回收算法】

  • 引用计数【通过一个数字判断当前对象是不是一个垃圾 】

  • 标记清除【给对象添加一个标记判断是否是一个垃圾】

  • 标记整理【跟标记清除差不多,只不过在回收的过程中会做一些事情,后面讲】

  • 分代回收【V8用到这个回收机制】

1.引用计数

核心思想:

  • 设置引用数,判断当前引用数是否为0

优点

  • 发现垃圾时立即回收
  • 最大限度减少程序暂停【内存快占满的时候,就进行垃圾回收并且释放】

缺点

  • 无法回收循环引用对象
  • 时间开销大【越多的对象需要修改,就消耗时间就越多】

2.标记清除实现原理

原理

  • 分标记和清除两个阶段,遍历所有对象,把活动对象就是用到的给标记出来,清除就是清除没有标记的对象

优点

  • 可以回收循环引用对象

缺点

  • 空间碎片化 地址不连续

    由于地址不连续,回收之后,空闲地址分散再各个角落,后续在想使用的时候,一旦新的想分配的空间跟这个匹配不上,那就尴尬了

  • 不会立即回收垃圾对象

3.标记整理算法原理

原理

是标记清除的增强,在清除阶段会先执行整理,然后移动对象位置,留出很多的大块统一的空间,一般跟着标记清除结合着使用

优点

  • 减少碎片化空间

缺点

  • 不会立即回收垃圾对象

★ V8引擎

认识V8

  • V8是一款主流的JavaScript执行引擎
  • V8采用即时编译
  • V8内存设限 64位操作系统内存上限不超过1.5G 32位的数值是不超过800W的

V8的GC算法

  • 分类回收【因为V8的内存是设有上线的,采用分代回收,不同代的采用不同的算法,从而实现高效的垃圾回收策略】
  • 空间复制
  • 标记清除
  • 标记整理
  • 标记增量

V8如何回收新生代对象

  • 内存一分为二
  • 小空间存储新生代对象(32M|16M)(from to)
  • 新生代指存活比较短的对象(局部作用域)

小空间存储新生代对象,又一分为二,为from to,对from进行标记整理算法,接着拷贝至to空间,最后再置换两个空间的状态,就完成了空间的释放操作

回收细节:拷贝过程中可能晋升至老生代,一轮GC还存活的会晋升,To空间超过25%的会晋升

V8如何回收老生代对象

  • 64位操作系统1.4G 32位700M

实现:

  • 开始主要使用标记清除
  • 新生代晋升的时候,空间不足时候,就使用标记整理对空间进行优化
  • 最后采用增量标记进行效率优化

新老对比

新:空间换时间,本来空间就小 老:数据多,不适合复制,也不适合一分为二,那样会有几百兆空间用不到

V8总结

  • js执行引擎

  • 内存设置上限(1.针对浏览器而言够用了,2.对GC机制来说,再大的话,操作时间超过1s,超过用户感知,不太好)

  • 分代回收思想(新生代 32M|16M--复制算法+标记整理算法,老生代 1.4G|700M--标记清除+标记整理+增量标记)细节-晋升

  • V8垃圾回收常见的GC算法


★ Performance

performance使用

浏览器-检查-性能performance-录制

延迟加载、暂停、持续性糟糕性能、性能差,都是我们的内存有问题了【内存泄漏,内存膨胀,频繁的垃圾回收】

监控的几种方法

内存的问题

界内内存问题的标准:

  • 内存泄漏:内存持续升高

  • 内存膨胀:多设备测试,如果多数设备都存在性能问题

  • 频繁的垃圾回收:通过内存变化图进行分析

监控内存的方式

  • 浏览器任务管理器工具【window有,Mac没找到】

  • timeline 时序图记录

  • 堆快照查找分离DOM

  • 判断是否存在频繁的垃圾回收

1.浏览器任务管理器工具【window有,Mac没找到】

window就是shift+esc快捷键然后弹窗里面找到对应的js脚本,查看消耗内存多少

2.timeline 时序图记录

就是浏览器-检查-performance-录屏,然后有个时序图,如果是长城,有升有降而且升也很平稳就说明正常的,如果有一段是一直上升的,没有下降的就不行,说明有问题

3.堆快照

什么是分离DOM

垃圾DOM就是界面不用,JS也没有用的,而分离DOM就是界面不用但是js还有引用,就是分离DOM,有这个DOM就是内存的DOM浪费,因为没啥用了,找到之后,置null就好了

利用浏览器堆、快照的功能,对浏览器页面进行拍照,存储memory-堆快照Heapsnapshot,拍照,搜索deta看看有没有分离DOM

4.判断是否存在频繁GC

因为GC的时候页面执行是停止的,所以频繁GC就频繁卡顿了,

  • timeline 频繁的上去下来上去下来
  • 任务管理器中数据频繁的增加减少增加减少