Performance Memory

JavaScript

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 全部崩溃。

通过观察 jsHeapSizeLimittotalJSHeapSize 这两个字段,可以用于监控当前的页面是否有耗尽内存的危险;同时,如果内存一直在涨,不见回落,很可能需要排查是否有潜在的内存泄漏危险。

需要注意的几点:

  1. 出于安全方面的考虑,API 并不会给出非常准确的数据,并且给出的数据会额外加上一些干扰(参考这个 Proposal,以及这个改动);
  2. 这不是一个标准的 API,目前只有 Chrome / Opera 可以使用(参考 caniuse);
  3. 安全问题是这个 API 没有被广泛实施的原因,详情可以参考这里的讨论;Proposal 也因为安全问题不好解决(参考这里给出的解释)而暂停了;
  4. 如果需要 Chrome 给出精确的内存数据,可以在启动的时候加上 --enable-precise-memory-info

MacOS 可以通过如下的命令启动 Chrome:

/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
  --enable-precise-memory-info
  1. performance.memory 无法通过 JSON.stringify 获取到数据(结果是 {}),一些分析和解决办法可以参考这篇文章