关于chrome:使用-Chrome-开发者工具分析内存问题

39次阅读

共计 3389 个字符,预计需要花费 9 分钟才能阅读完成。

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 的原创文章,尽在:” 汪子熙 ”:

正文完
 0