Chrome 浏览器在 performance
对象上加上了 memory
属性,通过获取 performance.memory
可以得到一组当前页面使用内存数据的信息。具体如下:
jsHeapSizeLimit
:表示当前页面最多可以获得的 JavaScript 堆大小;totalJSHeapSize
:表示当前页面已经分配的 JavaScript 堆大小;usedJsHeapSize
:表示当前页面 JavaScript 已经使用的堆大小。
这里,三个值的单位是字节(byte),且有恒定的不等式:jsHeapSizeLimit >= totalJSHeapSize >= usedJsHeapSize
。
Chrome 在分配内存的时候,会一次性向系统申请一块内存,然后在 JavaScript 需要的时候直接提供使用,因而 usedJSHeapSize
总是大于 usedJsHeapSize
的。如果 JavaScript 需要的内存多于已经申请的量,就会继续申请一块,直到达到 jsHeapSizeLimit
的上限,触发页面崩溃。注:根据之前 Gmail 团队的分享,Chrome 的进程模型,在浏览器打开非常多 Tab 的时候,会出现多个 Tab 共享一个进程的情况。因此,如果共享的几个页面中有一个内存大户,可能会导致一批 Tab 全部崩溃。
通过观察 jsHeapSizeLimit
和 totalJSHeapSize
这两个字段,可以用于监控当前的页面是否有耗尽内存的危险;同时,如果内存一直在涨,不见回落,很可能需要排查是否有潜在的内存泄漏危险。
需要注意的几点:
- 出于安全方面的考虑,API 并不会给出非常准确的数据,并且给出的数据会额外加上一些干扰(参考这个 Proposal,以及这个改动);
- 这不是一个标准的 API,目前只有 Chrome / Opera 可以使用(参考 caniuse);
- 安全问题是这个 API 没有被广泛实施的原因,详情可以参考这里的讨论;Proposal 也因为安全问题不好解决(参考这里给出的解释)而暂停了;
- 如果需要 Chrome 给出精确的内存数据,可以在启动的时候加上
--enable-precise-memory-info
;
MacOS 可以通过如下的命令启动 Chrome:
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
--enable-precise-memory-info
performance.memory
无法通过JSON.stringify
获取到数据(结果是{}
),一些分析和解决办法可以参考这篇文章。