使用 Chrome 开发者工具分析内存问题

DevTools 显示了按功能划分的内存分配细目。 默认视图是 Heavy (Bottom Up),它在顶部显示分配最多内存的函数。
Fix memory problems

内存泄漏很容易定义。 如果一个站点逐渐使用越来越多的内存,那么您就会出现泄漏。 但是内存膨胀有点难以确定。 什么是“使用过多内存”?

这里没有硬性数字,因为不同的设备和浏览器具有不同的功能。 在高端智能手机上流畅运行的同一页面在低端智能手机上可能会崩溃。

这里的关键是使用 RAIL 模型并关注您的用户。 找出哪些设备受用户欢迎,然后在这些设备上测试您的页面。 如果体验始终不佳,则页面可能超出了这些设备的内存容量。

Monitor memory use in realtime with the Chrome Task Manager

Shift + Esc 打开 Task manager:

允许查看 JavaScript memory:

这两列告诉您有关页面如何使用内存的不同信息:

memory 代表本机内存。 DOM 节点存储在本机内存中。 如果这个值在增加,DOM 节点就会被创建。

JavaScript Memory 列表示 JS 堆。 此列包含两个值。 您感兴趣的值是实时编号(括号中的数字)。 实时数字表示页面上可访问对象使用的内存量。 如果这个数字在增加,要么正在创建新对象,要么正在增长现有对象。

Visualize memory leaks with Timeline recordings

您还可以使用“Timeline”面板作为调查的另一个起点。 “Timeline”面板可帮助您可视化页面随时间的内存使用情况。

  • 在 DevTools 上打开 Timeline 面板。
  • 启用内存复选框。
  • 进行 recording.

提示:使用强制垃圾回收来开始和结束录制是一种很好的做法。 录制时点击垃圾回收按钮(强制垃圾回收按钮)强制垃圾回收。

考虑下面的例子:

var x = [];

function grow() {
  for (var i = 0; i < 10000; i++) {
    document.body.appendChild(document.createElement('div'));
  }
  x.push(new Array(1000000).join('x'));
}

document.getElementById('grow').addEventListener('click', grow);

每次按下代码中引用的按钮时,都会在文档正文中附加一万个 div 节点,并将一百万个 x 字符的字符串推送到 x 数组上。 运行此代码会生成一个时间轴记录,如下面的屏幕截图:

首先,解释用户界面。 概述窗格中的 HEAP 图(NET 下方)表示 JS 堆。 概览窗格下方是计数器窗格。 在这里,您可以看到按 JS 堆(与概览窗格中的 HEAP 图相同)、文档、DOM 节点、侦听器和 GPU 内存细分的内存使用情况。 禁用复选框会将其隐藏在图表中。

现在,将代码与屏幕截图进行比较分析。 如果您查看节点计数器(绿色图表),您会发现它与代码完全匹配。 节点数以离散的步骤增加。 您可以假设节点数的每次增加都是对grow() 的调用。 JS 堆图(蓝色图)并不那么简单。 根据最佳实践,第一次下降实际上是强制垃圾收集(通过按下收集垃圾按钮实现)。 随着记录的进行,您可以看到 JS 堆大小激增。 这是自然而然的:JavaScript 代码会在每次按钮点击时创建 DOM 节点,并在创建一百万个字符的字符串时做了大量工作。 这里的关键是 JS 堆结束时比开始时高(这里的“开始”是强制垃圾收集之后的点)。 在现实世界中,如果您看到这种增加 JS 堆大小或节点大小的模式,则可能意味着内存泄漏。

Discover detached DOM tree memory leaks with Heap Snapshots

DOM 节点只有在页面的 DOM 树或 JavaScript 代码中都没有对它的引用时才能被垃圾回收。 当一个节点从 DOM 树中移除但一些 JavaScript 仍然引用它时,就说它是“分离的”。分离的 DOM 节点是内存泄漏的常见原因。 下面介绍如何使用 DevTools 的堆分析器来识别分离的节点。

var detachedTree;

function create() {
  var ul = document.createElement('ul');
  for (var i = 0; i < 10; i++) {
    var li = document.createElement('li');
    ul.appendChild(li);
  }
  detachedTree = ul;
}

document.getElementById('create').addEventListener('click', create);

单击代码中引用的按钮会创建一个带有十个 li 子节点的 ul 节点。 这些节点被代码引用,但不存在于 DOM 树中,因此它们是分离的。

堆快照是识别分离节点的一种方式。 顾名思义,堆快照向您展示了在快照时间点内存在页面的 JS 对象和 DOM 节点之间的分布情况。

要创建快照,请打开 DevTools 并转到 Profiles 面板,选择 Take Heap Snapshot 单选按钮,然后按 Take Snapshot 按钮。

快照可能需要一些时间来处理和加载。 完成后,从左侧面板(名为 HEAP SNAPSHOTS)中选择它。

在类过滤器文本框中键入 detached 以搜索分离的 DOM 树。

突出显示为黄色的节点在 JavaScript 代码中直接引用了它们。 红色突出显示的节点没有直接引用。 它们之所以活着,是因为它们是黄色节点树的一部分。 通常,您希望关注黄色节点。 修复您的代码,使黄色节点的存活时间不会超过它需要的时间,并且您还可以摆脱作为黄色节点树的一部分的红色节点。

单击黄色节点以进一步调查。 在对象窗格中,您可以看到有关引用它的代码的更多信息。 例如,在下面的屏幕截图中,您可以看到 detachedTree 变量正在引用节点。 要修复这个特定的内存泄漏,您将研究使用 detachedTree 的代码,并确保它在不再需要时删除对节点的引用。

Identify JS heap memory leaks with Allocation Timelines

var x = [];

function grow() {
  x.push(new Array(1000000).join('x'));
}

document.getElementById('grow').addEventListener('click', grow);

每次按下代码中引用的按钮时,都会将一百万个字符的字符串添加到 x 数组中。

要记录分配时间线,请打开 DevTools,转到 Profiles 面板,选择 Record Allocation Timeline 单选按钮,按 Start 按钮,执行您怀疑导致内存泄漏的操作,然后按停止记录按钮(停止记录 按钮)完成后。

录制时,请注意分配时间轴上是否出现任何蓝色条,如下面的屏幕截图所示。

那些蓝条代表新的内存分配。 这些新的内存分配是内存泄漏的候选对象。 您可以放大条形以过滤构造器窗格以仅显示在指定时间范围内分配的对象。

展开对象并单击其值以在“对象”窗格中查看有关它的更多详细信息。 例如,在下面的屏幕截图中,通过查看新分配的对象的详细信息,您将能够看到它已分配给 Window 范围内的 x 变量。

Investigate memory allocation by function

使用 Record Allocation Profiler 类型查看 JavaScript 函数的内存分配。

(1) 选择记录分配分析器单选按钮。 如果页面上有工作人员,您可以使用“开始”按钮旁边的下拉菜单将其选为分析目标。

(2) 按开始按钮。

(3) 在要调查的页面上执行操作。

(4) 完成所有操作后按停止按钮。

DevTools 显示了按功能划分的内存分配细目。 默认视图是 Heavy (Bottom Up),它在顶部显示分配最多内存的函数。

Spot frequent garbage collections

如果您的页面似乎经常暂停,那么您可能遇到垃圾收集问题。

您可以使用 Chrome 任务管理器或时间线内存记录来发现频繁的垃圾收集。 在任务管理器中,频繁上升和下降的 Memory 或 JavaScript Memory 值表示频繁的垃圾收集。 在时间轴记录中,频繁上升和下降的 JS 堆或节点计数图表示频繁的垃圾回收。

确定问题后,您可以使用分配时间线记录来找出内存分配的位置以及导致分配的函数。

更多Jerry的原创文章,尽在:“汪子熙”:

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
让您的 Chrome 浏览器变得更快! 只需一次点击即可删除缓存,历史记录和Cookie。 当您使用浏览器(例如 Chrome)时,浏览器会将网站的一些信息保存在其缓存和 Cookie 。清除这些内容可以解决某些问题,例如网站上的加载或格式设置问题。 这个扩展可以消除: - 存储导航的历史。 - 缓存存储。 - 饼干 - 下载历史。 - 您可以按时间(从您想要删除的时间)进行选择。 此扩展不会消除: - 不要从自动填充表单删除数据。 - 它不会擦除存储在浏览器的密码。 - 它不会擦除文件系统和本地存储。 - 它不会消除应用程序缓存。 - 不删除加载项数据。 - 不会从WebSQL或IndexedDB删除数据。 为什么使用这个扩展? 1.在Chrome提高导航的速度。 由于RAM存储器和其获取的内存,缓存有时会降低系统和应用程序的速度。很多时候,它充满了垃圾信息,未来用户可能不需要这些信息。 主要目标是通过减少处理和数据收集来提高性能。由于存储大量缓存,机器的速度和性能受到阻碍。 提高系统和应用程序的性能是清除缓存的好处之一。 2.你得到一个新的更新版本的页面。 这有利于任何网页所做的更改都不会因缓存而反映出来。这就是为什么开发人员总是坚持清理缓存以查看他们已经实施的更改。 清除缓存时,您将清理浏览器以查找最新版本的网页并查看所做的更改。 3.保护您的隐私。 例如,缓存也可以存储来自某些网站的私人数据。登录凭据,手机号码等在使用公共计算机的情况下,下一个用户可以访问他们的敏感信息或个人信息。 以Facebook为例,您已登录到公共机器,并且在会话结束时尚未注销。访问下面设备的人可以访问他们的FB账户。这对隐私构成威胁。 在其他情况下,您的隐私与您有关,消除缓存是一个很好的选择。减少您的隐私威胁。 在其他浏览器 如果您使用的是 Safari、Firefox 或其他浏览器,请查看对应的支持网站以了解相关说明。 By Takeshi Nakamoto. 2018. 支持语言:Deutsch,English,English (UK),English (United States),Français,Türkçe,dansk,español,español (Latinoamérica),italiano,polski,português (Brasil),português (Portugal),svenska,русский,文 (简体),文 (繁體)

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

汪子熙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值