Bootstrap

浏览器内存溢出处理

内存溢出及处理

最近出现了一个问题,某次代码改动后,用户反馈浏览器可能卡死,或者点不动,基本判断是某个操作造成内存溢出,浏览器卡死。详细分析如下。

问题分析思路

1、如果一个新功能造成的 bug,造成浏览器直接崩溃,无法获取内存信息,也无法获取页面统计。因为新功能代码确定,可以从代码层面,白盒检查,二分法检查,分段排查代码中的问题。同时减少数据量量级,避免浏览器直接卡死的问题。

2、如果是未知原因造成的 bug,无法直接定位出错的功能和模块,可以在浏览器中调试。浏览器控制台 Performance 中,下面的属性可以参考:

screenshot 录屏:记录界面不同阶段的录屏,一般用于定性分析。

判断时间轴中 longtask 长任务,耗时超过 100ms,有问题通常红色标明,这个就反映了掉帧和界面卡顿。

Memory 内存:可以记录 Js heap, documents, nodes, listeners, GPU memory,反映了不同的消耗。

可以根据上述参数,先定性分析问题的大致方向。

具体案例分析

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

内存泄露堆栈溢出的本质问题

算法问题
循环引用
循环过多
闭包泄露
数据问题
数据量很大
脏数据、异常数据
数据类型不对

最后发现,代码中使用了 O(n ^ 2) 的时间复杂度,内循环中有大量消耗内存的函数。用户数据量可能上万,可能执行了上亿次调用函数操作,造成内存溢出。

    let len = 10000;
    for (let i = 0; i < len; i++) {
      for (let j = 0; j < len; j++) {
        fn(); // fn 是一个开销很大的函数
      }
    }

解决办法:避免在循环内部处理开销很大的操作,在循环外部提前算好,循环内部使用 map 形式获取计算结果,问题解决。

修改后的数据分析

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

参考资料

http://events.jianshu.io/p/fba13fc7537d

;