作者:玉伯
最近在项目中碰到 IE6-7 下的内存泄露,通过 Drip 能探测出来,问题也解决了。最近小组成员同时有在做前端质量工具,通过性能检测,可以排查出一些耗时较长的代码,但对内存泄露想不到好的自动化探测方式。本着集思广益的初衷,发了条微博:
通过 setTimeout 等方式,可以检测当前页面所在操作系统 CPU 的大体情况。请教万能的微博:有没有什么办法,通过 JavaScript 检测到当前页面所在操作系统的内存使用情况(比如是否持续上涨、存在内存泄露)?
CPU 占比探测
通过 setTimeout 的方式探测 CPU 已经不是秘密,去年腾讯的朋友在 Velocity 上分享过,北京有朋友还通过这个原理,几年前就实现了网页游戏中动画等耗时操作的自动调节。原理很简单:
var data = [] var t function pulse() { t && data.push(Date.now() - t) t = Date.now() setTimeout(pulse, 50) } pulse()
就是每隔 50ms 打一下点。理想情况下,data 的值应该是
data = [50, 50, 50, 50, ...]
但实际情况,data 会是
data = [51, 52, 50, 52, ...]
当 CPU 比较忙时,data 的数据变成
data = [81, 102, 90, 62, ...]
即 CPU 越忙,data 数据项会越大。这样,记录一系列 data 值,就可以绘制出 CPU 占比趋势图,和通过任务管理器看到的 CPU 趋势图非常接近。
上面只是原理说明,实际情况没这么简单。但很明显,通过这么一个简单的规律,就能实现用纯 JavaScript 来探测 CPU 占比了。
内存泄露探测
回到那条微博,是否也存在某种规律,使得可以用 JavaScript 来间接探测到内存泄露情况?
从微博的回复里还没看到有价值的信息。今天回家时,想到一种思路:
- 如果存在内存泄露,意味着浏览器在 GC 时,没有进行某些操作。
- 没有进行某些操作,意味着会节省一些 CPU 时间。
- CPU 耗时的变化,可以通过合理的打点探测出来。
似乎有点希望,回到家后,立刻写了点代码验证。但发现干扰因素太多,基线也很难确定。折腾了一个多小时,有些死结,很难突破。
于是停下来写这篇文章,看看大家有没有更好的思路。我们以为不可能的事情多了去,但不可能的事情往往存在可能,思路是无限的。
最后描述下我的具体需求:
有一个 a.html 页面,里面有 JS 业务代码,以及单元测试代码。
通过前端测试系统,我们可以把 a.html 自动跑在各个浏览器上,比如 IE6/7/8/9。
现在已经可以自动得到 a.html 在各个浏览器下的单元测试结果,以及一些性能指标。
现在想进一步,想通过单元测试代码,也能探测出当前页面是否存在内存泄露。
页面存在内存泄露时,典型的现象是,不断刷新当前页面,内存占用不会归位,而会一直往上涨。