排查Javascript内存泄漏案例(一)

这篇具有很好参考价值的文章主要介绍了排查Javascript内存泄漏案例(一)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Chrome DevTools里的Performance面板和Memory面板可以用来定位内存问题。

如何判断应用发生内存泄漏?

为了证明螃蟹的听觉在腿上,一个专家捉了只螃蟹并冲它大吼,螃蟹很快就跑了。然后捉回来再冲它吼,螃蟹又跑了。最后专家把螃蟹的腿都切了,又对着螃蟹大吼,螃蟹果然一动不动……
定位问题首先要能找到问题的大概方向

如果自己都不知道页面在使用过程中哪些步骤会导致内存增长,那很可能就会错把一个正常的内存增长当作内存泄漏来排查,最后查了半天白忙活。 其实一个单页应用在使用过程中,内存发生增长是很合理的。例如在开发过程中,为了优化使用体验,我们可能会对部分数据进行缓存,这部分缓存的数据其实也会导致内存占用的升高,但它是符合预期的。

因此,排查内存泄漏的第一步,就是要先梳理一遍自己的代码,看一下哪部分内存的升高是合理的,哪部分内存的升高是不合理的。

首先进入无痕模式(快捷键ctrl+shift+N),避免一些浏览器插件或其它因素影响到对内存的分析。

Performance和Memory都可以用来定位内存问题,先用谁呢?

在无法确定是否发生内存泄漏时,我们可以先使用Performance来录制一段页面加载的性能变化,先判断是否有内存泄漏发生。排查Javascript内存泄漏案例(一)
在开始之前,先点击一下Collect garbageclear来保证内存干净,没有其他遗留内存的干扰。然后点击Record来开始录制,并且同时也要点击页面上的开始按钮,让代码跑起来。等到代码结束后,再点击Record按钮以停止录制,录制的时间跟代码执行的时间相比会有出入,只要保证代码是完全执行完毕的即可。停止录制后,会得到如下的结果:排查Javascript内存泄漏案例(一)

如果录制结束后,看到内存的下限在不断升高的话,就要注意了 —— 这里有可能发生了内存泄漏。排查Javascript内存泄漏案例(一)

除了内存增长曲线,Nodes(Dom节点数曲线)、Document曲线以及Listener曲线也同样值得关注,有时候它们对内存问题的定位也很有帮助。

当怀疑发生了内存泄漏的时候,就可以用Memory面板来进一步定位泄漏的源头了。

Memory面板定位内存泄漏代码位置

Memory选项主要是用来录制堆内存的快照,为进一步分析内存泄漏的详细信息。为什么不一开始就直接使用Memory,反而是先使用Performance。因为刚开始就说了,内存增长不表示就一定出现了内存泄漏,有可能是正常的增长,直接使用Memory来分析可能得不到正确的结果。
排查Javascript内存泄漏案例(一)
首先清除缓存,在配置选项中选择堆内存快照。内存快照每次点击录制按钮都会记录当前的内存使用情况,我们可以在程序开始前点击一下记录初始的内存使用,代码结束后再点一下记录最终的内存使用,中间可以点击也可以不点击。最后在快照列表中至少可以得到两个内存记录:排查Javascript内存泄漏案例(一)
初始内存暂时不深究,选择列表的最后一条记录,然后在筛选下拉框选择最后一个,即第一个快照和第二个快照的差异。切换后,你就能看到两个快照之间新生成的对象。你可以选择其中一项点开,看看它的retaining tree里面保留了哪些对象没有释放。

排查Javascript内存泄漏案例(一)

这里重点说一下Shallow Size和Retained Size的区别:

Shallow Size:对象自身占用的内存大小,一般来说字符串、数组的Shallow Size都会比较大
Retained Size:这个是对象自身占用的内存加上无法被GC释放的内存的大小,如果Retained SizeShallow Size相差不大,基本上可以判定没有发生内存泄漏,但是如果相差很大,例如上图的Object,这就表明发生了内存泄漏。

再来细看一下Object,任意展开一个对象,可以在树结构中发现每一个对象都有一个全局事件绑定,并且占用了较大的内存空间。解决本案例涉及的内存泄漏也比较简单,就是及时释放绑定的全局事件。
排查Javascript内存泄漏案例(一)
在具体项目中排查内存泄漏问题时,会有很多奇怪的变量,除去教程demo代码比较简单外,提前准备号一个合理的debug环境也很重要,下面例举了个人觉得有帮助的措施去排查内存问题:

  • 尽量使用没有混淆的代码:打包后的代码往往经过了混淆和压缩,在生产环境上这是必要的,但在debug时却会成为我们的绊脚石,不便于阅读。
  • 排查问题时使用production模式编译出来的代码:Dev模式下往往会开启一些方便开发的特性,例如热更新等。但它们可能会占用一部分的内存,影响到内存问题的排查,所以建议还是使用production模式编译出来的代码进行问题排查。
  • 屏蔽所有浏览器插件:屏蔽浏览器插件最快的方式就是打开无痕窗口。浏览器插件给我们带来很多便利,但插件注入的额外逻辑有时也会影响内存问题的排查。例如vue-devtools会记录下每一个vuex mutaions,导致内存无法释放。
  • 在现场打内存快照,便于跳转到源代码所在行:尽管devTools记录下来的内存快照文件可以单独加载展示,但还是建议在记录下内存快照的时候“趁热”分析,因为这时还能从retaining tree上跳转到代码所在行,有时候对定位问题也很有帮助。排查Javascript内存泄漏案例(一)

其它内存问题

1,快照里有一些“Detached DOM tree”,是什么意思?

一个DOM节点只有在没有被页面的DOM树或者Javascript引用时,才会被垃圾回收。当一个节点处于“detached”状态,表示它已经不在DOM树上了,但Javascript仍旧对它有引用,所以暂时没有被回收。通常,Detached DOM tree往往会造成内存泄漏,我们可以重点分析这部分的数据。

2,Shallow sizeRetained size,它们有什么不同?
  • Shallow size: 这是对象自身占用内存的大小。通常只有数组和字符串的shallow size比较大。
  • K这是将对象本身连同其无法从 GC 根到达的相关对象一起删除后释放的内存大小。 因此,如果Shallow Size = Retained Size,说明基本没怎么泄漏。而如果Retained Size > Shallow Size,就需要多加注意了。
3, Memory里的Summary视图, Comparison视图, Dominators视图和Containment视图分别有什么不同呢?

排查Javascript内存泄漏案例(一)

1). Summary view:当前内存快照的一个概览。排查Javascript内存泄漏案例(一)
我们先介绍一下这个视图下的每一列是什么意思:
- Constructor: 对象的构造器。
- Distance:与root的距离。距离越大,处理和加载这个对象的时间就越长。
- Object Count:指定构造器创建的对象的数量。
- Shallow Size:对象自身占用内存的大小。
- Retained Size:释放掉该对象后,能释放掉的内存。

在这个视图下可以看到当前页面内存的具体构成,但如果想定位内存问题,下面的Comparison view会更加有用。

2). Comparison view:这个选项下可以对比两份内存快照之间的差异。默认是跟上一份快照做对比,当然也可以选择任意两份内存做对比。
排查Javascript内存泄漏案例(一)

这个视图下每一列的数据有点不同:
 - Constructor: 对象的构造器。
 - #New: 该对象构造器下有多少新对象被创建。
 -  #Deleted: 该对象构造器下有多少新对象被销毁 。
 -  #Delta: 是 #New - #Delete 的差值 。
 - Alloc.Size:两份快照之间新分配的内存。
 -  Freed Size: 两份快照之间释放掉的内存。
 - Size Delta:Alloc Size - Freed Size 的差值。

3), Containment view:提供了一个自下而上的视图,它允许你浏览和探索堆内存的内容。可以用它来分析一些全部变量的引用情况(如window)。
排查Javascript内存泄漏案例(一)

4), Statistics views:用饼图的形式展示各个类型对象的内存占比
排查Javascript内存泄漏案例(一)

4,发现有一个叫feedback_cell的字段经常出现,它是什么?是它导致了内存泄漏吗?

排查Javascript内存泄漏案例(一)
放心,它不会造成内存泄漏。它是v8对频繁运行的热代码做出的优化,会被v8自己回收。

5,Constructor下的(array), Array, (closure), (compiled code)都对应的哪些内容?

(closure): 函数闭包持有的内存引用。
(array, string, number, regex): 包含着一系列对象,这些对象的属性上有对应类型变量的引用。
(compiled code): Javascript引擎(如V8)为了加快运行速度,会对代码进行一次编译。(compiled code)顾名思义就是指与编译后的代码相关联的内存。
Detached HTMLDivElement等:代码里对指定类型Dom节点的引用。文章来源地址https://www.toymoban.com/news/detail-469251.html

到了这里,关于排查Javascript内存泄漏案例(一)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • jvm内存溢出排查(使用idea自带的内存泄漏分析工具)

    想分析堆内存溢出,一定在运行jar包时就写上参数 -XX:+HeapDumpOnOutOfMemoryError ,可以看我之前关于如何运行jar包的文章。若你没有写。可以写上参数,重启你的项目,等你的项目发生下一次堆内存溢出异常,在运行的同级文件夹,将产生类似这样一个文件 java_pid74935.hprof ,若你

    2024年02月09日
    浏览(45)
  • 使用Visual Leak Detector排查内存泄漏问题

    目录 1、VLD工具概述 2、下载、安装VLD 2.1、下载VLD 2.2、安装VLD 3、VLD安装目录及文件说明

    2024年02月07日
    浏览(32)
  • JavaScript 内存泄漏

    分配内存 内存中的读写 垃圾回收 对于内存的使用,所有语言基本都是一样的,只是更底层的语言在对于 ”分配内存“ 和 ”使用内存“ 是明确的,但是在高级语言中(比如本文的 JS)是隐藏了。 JS 中在定义一个变量时,就已经分配好了一个内存; 同时,内部也提供好了垃

    2024年02月02日
    浏览(29)
  • 开源WebRTC库放大器模式在采集桌面图像时遇到的DPI缩放与内存泄漏问题排查

    目录 1、在非100%的显示比例下放大器采集到的桌面图像不全问题 1.1、通过manifest文件禁止系统对软件进行缩放

    2024年02月08日
    浏览(33)
  • C++内存泄露排查的一个案例

    背景: 这熟悉的线条. 请求量没啥波动, 不用怀疑, 就是内存泄露了. 方案一 Valgrind Valgrind可以用来检测是否有非法使用内存的问题, 如: 访问未初始化的内存,访问数组越界, 忘记释放动态内存的问题; 首先需要定位是哪个进程的内存泄露. 使用top命令, 然后shift+m按照内存排序, 找

    2024年02月13日
    浏览(29)
  • node内存泄漏耗尽: FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript

    首先看到这种就是内存泄漏,问题找准了,接下来就是疯狂百度,csdn搜索,试了3个方法,最后一个有用。   执行npm命令报错:FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of me 字面意思:JavaScript堆内存不足。因为Node 是基于V8引擎,在 Node 中通过

    2024年02月13日
    浏览(32)
  • Chrome Devtools 调试指南

    Chrome DevTools是一套内置在Google Chrome浏览器中的强大调试工具,用于前端开发和调试网页。它们提供了丰富的功能,包括检查和修改DOM元素、调试JavaScript、分析性能、查看网络活动等。以下是一个基础的Chrome DevTools调试指南: 打开Chrome DevTools 通过菜单打开 :点击Chrome浏览器

    2024年01月20日
    浏览(27)
  • 使用Selenium与Chrome DevTools交互

    目录 为什么我们应该自动化Chrome开发工具? 如何打开Chrome DevTools 元素 控制台 源代码

    2024年02月15日
    浏览(41)
  • chrome插件开发实例06-定制自己的Chrome DevTools调试工具

    目录 Chrome DevTools 调试工具 演示 ​编辑 源码  devtools.html devtools.js panel.html

    2024年02月13日
    浏览(31)
  • Chrome DevTools开发者工具调试指南

    Chrome DevTools是Chrome浏览器内置的一套开发者工具,提供了强大的调试和分析网页的功能。以下是使用Chrome DevTools进行调试的简要指南: 1:打开Chrome DevTools: 在Chrome浏览器中,右键点击网页上的任意位置,选择\\\"检查\\\"或\\\"审查元素\\\",或者使用快捷键Ctrl+Shift+I(Windows)/Cmd+Optio

    2024年02月06日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包