对于前端的“内存泄漏”这个东西,说实话我只在书上看到过:前端
闭包、匿名函数和事件绑定尤为容易形成内存泄漏。浏览器
然而这些操做形成的“内存泄漏”到底是什么样子的?如何排查?虽然很好奇,却不得而知。直到此次公司应用频繁出现浏览器崩溃的状况,我受命解决这个问题,才开始研究内存泄漏的排查方法,及排查工具。markdown
我司的应用在客户现场反馈过来的问题是:在某几台固定的电脑上频繁出现浏览器崩溃的状况。我问现场要了机器的配置,发现这些问题机器的可用运行内存,连三个 G 都没有,在别的内存较大的机器上这种崩溃的状况较少发生。闭包
若是浏览器频繁出现“崩溃”、“卡顿”等状况,则基本能够判断为浏览器内存占用较高,而 CPU 分配给浏览器的内存空间是很小且有限的,若是内存占用濒临极限,就会出现卡顿,若是内存占用溢出,浏览器就会崩溃。框架
Chrome 浏览器,F12 打开开发者工具,涉及公司机密,我就先找了阮一峰老师的 ES6 网站演示。函数
点击这个按钮启动记录,而后切换到网页进行操做,录制完成后点击 stop 按钮,开发者工具会从录制时刻开始记录当前应用的各项数据状况工具
选中JS Heap
,下面展示出来的一条蓝线,就是表明了这段记录过程当中,JS 堆内存信息的变化状况。网站
关于“堆”和“栈”的概念,简单的说,开发者建立的对象都在堆里,栈空间是留给系统来分配的spa
有大佬说,根据这条蓝线就能够判断是否存在内存泄漏的状况:若是这条蓝线一直成上升趋势,那基本就是内存泄漏了code
其实我以为这么讲有失偏颇,JS 堆内存占用率上升并不必定就是内存泄漏,只能说明有不少未被释放的内存而已,至于这些内存是否真的在使用,仍是说确实是内存泄漏,还须要进一步排查。
开发者工具的 Memory 选项,能够更精确地定位内存使用状况。
当生成了第一个快照的时候,开发者工具窗口已经显示了很详细的内存占用状况。
字段解释:
Constructor
— 占用内存的资源类型Distance
— 当前对象到根的引用层级距离Shallow Size
— 对象所占内存(不包含内部引用的其它对象所占的内存)(单位:字节)Retained Size
— 对象所占总内存(包含内部引用的其它对象所占的内存)(单位:字节)将每项展开能够查看更详细的数据信息。
咱们再次切回网页,继续操做几回,而后再次生成一个快照。
这边须要特别注意这个 #Delta ,若是是正值,就表明新生成的内存多,释放的内存少。其中的闭包项,若是是正值,就说明存在内存泄漏。
下面咱们到代码里找一个内存泄漏的问题:
单页应用容易出现这个问题。
若是是普通网站,切换菜单页面就刷新了,全部内存会被回收,进行再分配,不太会出现严重的内存泄漏问题。
最后,关于内存泄漏,我发现几乎全部网站都存在这个问题,而且有不少的内存泄漏,都是第三方库和框架的打包文件带来的。因此说,对于内存泄漏,只要不是特别严重,开发者是没有单独处理的必要的。
然而我司的应用就另当别论了,,
别问我有多少内存泄漏。
五十三万个,我日。。