目录

web网页内存泄漏

主要的内存泄漏来源

利用谷歌DevTool定位内存泄漏问题

性能Performance

主要功能

Performance insights性能数据分析

Memory内存

三种模式

相关概念

解决内存泄漏问题

第一步 :是否内存泄漏:js堆直增不降;降的不多

第二步:找到导致内存泄漏的函数或者变量,以及出现的时机

第三步:几种常见的内存泄漏。解决:优化代码,手动垃圾回收

总结


web网页内存泄漏

web 网页内存泄漏指网页在运行过程中,占用的内存越来越多,而无法自动释放,从而导致网页性能下降或崩溃。

主要的内存泄漏来源有:

1. 没有及时清除定时器或回调函数
如果定时器或回调函数中的变量一直被引用,但没有及时清除定时器,这些变量的内存无法释放,导致内存占用越来越高。

2. 没有及时移除不再需要的事件监听器
如果一直不停地添加事件监听器但没有及时移除,这也会导致占用的内存越来越高。

3. 闭包
如果一个闭包的变量一直被引用,其占用的内存也无法释放。

4. DOM 节点引用未清除
如果持续生成 DOM 节点,但没有及时移除不再需要的节点,DOM 节点会越来越多,占用的内存也会上升。

5. 第三方库或插件未正常释放内存
一些第三方库或插件如果本身存在内存泄漏,也会影响网页的内存占用。

初次了解到内存泄漏,还是因为在我的实际项目中网页经常卡顿甚至直接崩溃,占用的cpu和js堆极高。那么我是如何定位到是内存泄漏导致的网页卡顿呢,主要是依靠我们常用的谷歌浏览器自带的devtool工具。

利用谷歌DevTool定位内存泄漏问题

性能Performance

测试网址:https://googlechrome.github.io/devtools-samples/jank/

操作:f12打开谷歌控制台,点开性能Performance工具栏。

主要功能:

1. 模拟移动设备,模拟cpu降速,网络降速

2. 可以使用录制⏺来操作自己的页面生成报告,分析报告中的指标

3. 卡顿主要表现指标:FPS 帧率越低,颜色越红,体验越差。快捷键:Command+Shift+P (Mac) or Control+Shift+P (Windows, Linux)

4. CPU占用CPU与摘要中的圆形图表对应

5. 长任务:右上角有红色三角,需要警惕,长任务耗时异常。

点击长任务可定位到具体哪一行代码导致耗时

6. 提供屏幕截图

Performance insights性能数据分析

使用:控制台右上角更多工具–》Performance insights性能数据分析

这个工具的作用其实和上一个性能作用是一样的。但是新增了两个面板分别是insight面板和detail面板

  • ·insight面板:识别和解决潜在的性能问题。并分析用户核心性能指标。直接告诉你哪里有问题

  • ·detail面板:定位代码文件,指出问题,提出解决建议。例如:点击长任务块,会告诉你怎么优化,具体代码位置。

Memory内存

使用:

三种模式

堆快照

控制:支配者视图显示支配者树,可用于查找累积点。这个视图有助于确认没有意外的对象引用仍然存在,并且删除/垃圾收集实际上正在工作。

摘要:“摘要”视图显示按构造函数名称分组的对象。使用它根据构造函数名称分组的类型 搜索对象(及其内存使用)。它对于跟踪 DOM 泄漏尤其有帮助。

统计数据:;

比较:比较两次快照的变化

时间轴上的分配插桩

主要关注:如图蓝色条表示在时间线末尾仍然存在的对象,灰色条表示在时间线末尾分配但后来被垃圾收集的对象

分配采样

查看函数引用tree

相关概念

浅层大小 Shallow size:对象本身持有的内存大小

保留大小 Retained size:定义:在删除对象本身及其从 GC Root中无法访问的依赖对象时释放的内存大小。也就是当前对象自身大小加上对象直接或间接引用的其他对象的大小总和

GC Root:当前时刻存活的对象。https://pic1.zhimg.com/v2-f79a0f0a6d3c485bce3768af596e7b9c_b.webp

距离:使用节点的最短简单路径显示到根的距离。

解决内存泄漏问题

第一步 :是否内存泄漏:js堆直增不降;降的不多

用Chrome 任务管理器查看你的页面当前使用了多少内存。工具:任务管理器

用性能监视器观察js堆变化,dom节点变化,是否符合升降规律

用内存使用堆快照识别 DOM 树(导致内存泄漏的常见原因)。杀手级别功能。

用内存通过时间轴记录可视化内存使用情况 蓝色条高于分配线需要关注,属于新分配的内容。

第二步:找到导致内存泄漏的函数或者变量,以及出现的时机

去除干扰:多拍几次快照,多对比,

关注新对象数量和增量两个指标。看一直都保持增量的数据并结合新对象树去分析某个特定操作前后导致内存增加

查找retainer树,定位具体代码位置,数据引用位置

第三步:几种常见的内存泄漏。解决:优化代码,手动垃圾回收

DOM 元素泄漏:在 JavaScript 中,当一个 DOM 元素被移除或者替换时,如果没有正确地清理事件监听器、定时器等资源,那么这些资源就会一直占用内存,从而导致内存泄漏。解决方案是在移除或替换 DOM 元素时,手动清理相关资源。

闭包泄漏:在 JavaScript 中,当一个函数返回另一个函数时,该函数和其变量的作用域就会形成一个闭包。如果这个闭包在外部函数执行完毕后仍然被引用,那么它所占用的内存就会一直存在,从而导致内存泄漏。解决方案是在使用闭包时,尽量避免在闭包内引用外部变量,或者在闭包不再使用时手动将其置为 null

全局变量泄漏:在 JavaScript 中声明全局变量时,全局变量会一直存在于内存中,即使它们在代码执行完毕后已经失去了作用,也不会被自动回收,从而导致内存泄漏。解决方案是在变量不再使用时手动将其置为 null。

总结

内存泄漏问题的定位和解决不是一下子就能搞定的,特别是问题定位的时候要多利用工具,多比较样本,同时也会花费一定时间去定位到。
关注内存泄漏的同时,相信您对网页性能提升,问题定位也感兴趣。热烈欢迎您使用智子监控系统:基于未来云日志中心和@xes/web-log SDK创建,专为监控前端web应用的性能和错误而设计。当你的线上项目出现异常和错误时❌,智子监控系统可以通过知音楼消息立即通知开发者,第一时间发现问题,并帮助你快速定位与修复,最大限度减少线上损失!