排查 Web App 的 JS 内存泄露小结

转载地址:https://testerhome.com/topics/3589

排查Web App的JS内存泄露小结

一、概述 
所测试的项目是带角色交互的APP,其教师端是Hybird APP(主要控件是Native,页面内容基于Webview),学生端是一个基于Webview的APP。在测试过程中,几十次使用教师端翻页按钮,出现教师端概率性Crash。或者教师端将带音频和视频的内容分发到学生端,点击学生端的触发音视频按钮,其学生端高概率的Crash。经过多次教师端连续发送到学生端,发现学生端会出现页面渲染慢,有时无法将内容内容显示清楚,见下图:

教师端使用翻页按钮发送多道题目,教师端操作后卡顿或者崩溃,见下图:

二、现象分析
出现页面内容页面加载缓慢,可初步判断是渲染慢,可能是Pad性能不足或者程序内存泄漏。出现教师端发题Crash或者操作教师端加载缓慢,也可能是内存泄漏。所以我第一时间把出现问题Pad连接到PC,查看CPU和内存使用情况,见下图:

其次,出现学生端崩溃的时候将Pad连接到DDMS,查看报错log,由log可以看出在使用音视频的时候出错,最终导致浏览器崩溃,见下图:

最后,由渲染慢导致页面加载慢,以及崩溃的日子可初步排查是内存泄漏,可尝试使用Chrome Profiles分析。

三、使用Chrome Profiles分析
Google Chrome浏览器提供了非常强大的JS调试工具,Heap Profiling便是其中一个。Heap Profiling可以记录当前的堆内存(heap)快照,并生成对象的描述文件,该描述文件给出了当时JS运行所用到的所有对象,以及这些对象所占用的内存大小、引用的层级关系等等。这些描述文件为内存泄漏的排查提供了非常有用的信息。什么是heap?JS运行的时候,会有栈内存(stack)和堆内存(heap),当我们用new实例化一个类的时候,这个new出来的对象就保存在heap里面,而这个对象的引用则存储在stack里。程序通过stack里的引用找到这个对象。例如var a = [1,2,3];,a是存储在stack里的引用,heap里存储着内容为[1,2,3]的Array对象。
JS程序的内存溢出后,会使某一段函数体永远失效(取决于当时的JS代码运行到哪一个函数),通常表现为程序突然卡死或程序出现异常。这时我们就要对该JS程序进行内存泄漏的排查,找出哪些对象所占用的内存没有释放。这些对象通常都是开发者以为释放掉了,但事实上仍被某个闭包引用着,或者放在某个数组里面。
有时我们需要在程序中加入观察者模式(Observer)来解藕一些模块,但如果使用不当,也会带来内存泄漏的问题。排查这类型的内存泄漏问题,主要重点关注被引用的对象类型是闭包(closure)和数组Array的对象。下面以实际项目为例:
首先,选中“Take Heap Snapshot”,点击“Take Heap Snapshot”按钮,就可以拍下当前JS的heap快照,如下图所示:

其次,点击Pad端不同业务操作按钮,结合柱状图可查看不同操作的内存释放情况,见下图:

最后,基于前面的内存释放情况,可使用JS的heap快照查看对象应用关系。点击其中一个对象,能看到对象的引用层级关系,红色部分表示内存内存泄漏。查看到实际应用多,且带有红色,表示内存泄漏,见下图:

四、结语
JS的灵活性既是优点也是缺点,平时写代码时要注意内存泄漏的问题。当代码量非常庞大的时候,就不能仅靠复查代码来排查问题,必须要有一些监控对比工具来协助排查。
之前排查内存泄漏问题的时候,总结出以下几种常见的情况:
1.闭包上下文绑定后没有释放;
2.观察者模式在添加通知后,没有及时清理掉;
3.定时器的处理函数没有及时释放,没有调用clearInterval方法;
4.视图层有些控件重复添加,没有移除。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值