分析内存使用情况 (JavaScript)
[此文档是初定版,随时可能进行更改。]
JavaScript 内存分析器在 Visual Studio 2012 更新 1 和 Visual Studio 2013 中提供,旨在帮助你了解内存使用量和查找使用 JavaScript 为 Windows 生成的 Windows 应用商店应用程序中的内存泄漏。
JavaScript 内存分析器可以为你执行以下操作:
在菜单栏上,选择“调试”和“性能和诊断”。
默认情况下,将分析当前启动项目。 如果要更改分析目标,请选择“更改目标”。
以下选项可用于分析目标:
“启动项目”。 分析当前启动项目。 如果你要在远程计算机上运行应用程序,则必须选择此选项,这是默认值。
“正在运行的应用程序”。 允许你从正在运行的应用程序的列表中选择应用程序。 在远程计算机上运行应用程序时,不能使用此选项。
当你无权访问源代码时,请使用此选项分析计算机上运行的应用程序的内存使用量。
“已安装的应用程序”。 允许你选择要分析的已安装应用程序。 在远程计算机上运行应用程序时,不能使用此选项。
当你无权访问源代码时,请使用此选项分析计算机上安装的应用程序的内存使用量。 如果要分析你自己的应用程序开发之外的任何应用程序的内存使用量,此选项也很有用。
启动内存分析器时,可能会显示一个“用户帐户控制”窗口,要求你提供运行 Visual Studio ETW Collector.exe 的权限。 选择“是”。
与应用程序交互以测试相关的内存使用量方案并查看内存关系图,如以下各节所述。
实时内存使用量摘要 。 使用内存使用量图来查找内存使用量的突然增长或由特定操作导致的连续增长的内存使用量。 使用实时内存使用量摘要视图来拍摄堆的快照,这些快照在内存使用量图中显示为一个集合。
以下是可帮助你更有效地使用 JavaScript 内存分析器的工作流步骤。 如果你怀疑你的应用程序有内存泄漏,这些步骤将非常有用。
如果有可能,请将你的应用程序置于遭遇内存泄漏之前的状态。 例如,这可能是在大型 DOM 刚要转变之前、加载特定页时或启动应用程序时。
切换到 Visual Studio 并拍摄第三个快照。
下图演示了第二个和第三个快照的示例:
通过拍摄此工作流中的第三个快照,可以筛选出与内存泄漏不相关的、从基线快照到第二个快照的更改。 例如,预计可能有一些更改(如在页面上更新页眉和页脚)会造成内存使用量的更改,但可能与内存泄漏不相关。
使用内存使用量视图,调查从第二个快照到第三个快照在堆大小和对象计数方面的差异。 下面是一些提示:
检查对象堆大小和对象计数的差异视图(带有红色箭头和绿色箭头的链接)。 差异视图使用彩色编码来突出显示从前一个快照更改的项。 蓝色指示已修改的元素或对象。 绿色表示已添加的元素或对象。
如果某个项是未修改的(黑色),则不泄漏内存。 只有已添加或已修改的项表示潜在的内存泄漏。
使用这些视图可根据应用程序的已知行为来查找意外的对象大小或对象计数方面的较大变化。
若要查看差异视图中的对象植根于全局对象中的位置,以防止将其作为垃圾回收,请打开对象的快捷菜单,然后选择“在根视图中显示”。
实时内存使用量摘要视图提供了正在运行的应用程序的内存使用量图,以及所有快照摘要图块的集合。 在此视图中,可以执行拍摄快照、分析摘要信息和导航到其他视图等基本任务。 停止收集数据后,内存关系图将消失,你只能看到快照摘要视图。
内存关系图显示应用程序进程内存的活动视图,包括专用字节、本机内存和 JavaScript 堆。 内存关系图是进程内存的可滚动视图。 该窗口类似于下方所示:
![JavaScript 内存分析器内存图 JavaScript 内存分析器内存图](http://i.msdn.microsoft.com/dynimg/IC680019.png)
Associate source code with memory usage data), an inverted triangle appears in the memory usage graph to indicate when that section of code is reached. " data-guid="809a68e01a7d2b1635f07a95d27145d6" 如果你已向应用程序代码中添加用户标记(请参见将源代码与内存使用量数据关联),则内存使用量图中将出现一个倒三角形,用于指示何时到达该代码部分。
内存关系图中显示的一些内存是由 JavaScript 运行时分配的。 你无法在应用程序中控制此内存使用量。 当你拍摄第一个快照时,关系图中显示的内存使用量会增加,之后该使用量会对每个附加的快照按最低限度增加。
若要拍摄应用程序内存使用量的当前状态的快照,请从内存关系图中选择“拍摄堆快照”。 快照摘要图块会同时出现在实时内存使用量摘要(在应用程序运行时)和快照摘要(在应用程序停止时)中,它提供了有关 JavaScript 堆的信息和指向更详细的信息的链接。 如果拍摄了两个或更多快照,则快照将提供更多信息以将其数据与前一个快照的数据进行比较。
JavaScript 内存分析器会在拍摄每个快照之前强制进行垃圾回收。 这有助于确保各个运行中的结果更加一致。
潜在问题计数(用蓝色信息图标标记)。 此数字(如果存在)标识潜在内存问题(例如,节点未附加到 DOM)的数目。 此计数将链接到快照的控制器视图,此视图按照问题类型进行排序以突出显示潜在问题。工具提示中将显示问题的说明。
堆大小。 此数量包括由 JavaScript 运行时引擎添加到 JavaScript 堆的 DOM 元素和对象。 堆大小将链接到快照的控制器视图。
堆大小差异。 此值显示当前快照的堆大小和前一个快照的堆大小之间的差异。 如果内存增加,则该值后跟一个红色向上箭头;如果内存减少,则该值后跟一个绿色向下箭头。 如果快照间的堆大小未发生更改,则将显示文本“无更改”而不是数字。 对于第一个快照,将显示文本“基线”。 堆大小差异将链接到快照差异的控制器视图。
对象计数。 此计数仅显示在应用程序中创建的对象,并筛选出由 JavaScript 运行时创建的内置对象。 对象计数链接到快照详细信息的类型视图。
对象计数差异。 这将显示两个值:第一个值是自前一个快照以来添加的新对象的数量;第二个值是自前一个快照以来移除的对象的数量。 例如,+25 / -10 表示添加了 25 个对象,并移除了 10 个对象。 如果对象总计数增加,则此信息后面会跟一个红色向上箭头;如果对象总计数减少,则此信息后面将跟一个绿色向下箭头。 如果对象计数未发生更改,则将显示文本“无更改”而不是数字。 对于第一个快照,将显示文本“基线”。 对象计数差异链接到快照差异的类型视图。
快照摘要可能显示堆大小或对象计数无更改或减少,但仍可能隐藏内存泄漏。 当新创建的对象的数量或大小小于已删除对象(例如,作为垃圾回收的结果)的数量或大小时,可能会出现此情况。
可以在快照详细信息视图中查看有关每个快照的内存使用量的详细信息。
从快照摘要视图中,选择一个链接来查看快照详细信息。 例如,默认情况下,堆大小链接将在控制器视图打开的情况下打开快照详细信息。
此图显示了快照详细信息的控制器视图,以及按问题类型排序的内存使用量数据,并突出显示了潜在问题。
![Snapshot details view showing potential issues Snapshot details view showing potential issues](http://i.msdn.microsoft.com/dynimg/IC680021.png)
在快照详细信息视图中,你可以通过从工具栏中选择相应的选项来按控制器、类型或根查看内存使用量数据:
支配者。 显示堆中所有对象的列表,按保留大小排序。 如果你从快照摘要中的潜在问题链接打开此视图,则将按问题类型对对象进行排序以突出显示潜在问题。 工具提示提供每个问题的说明。
类型。 显示对象的实例计数和总大小,按对象类型分组。 默认情况下,它们按实例计数排序。
根。 显示从根对象到子引用的对象的分层视图。 默认情况下,子节点按保留的大小列排序,最大的排在顶部。
标识符。 最能标识对象的名称。 例如,对于 HTML 元素,快照详细信息显示 ID 特性值(如果使用)。
保留的大小。 对象大小加上所有没有其他父对象的子对象的大小。 从实用的角度而言,这是对象保留的内存量,因此,如果你删除对象,则将回收指定的内存量。
在 JavaScript 内存分析器中,可以在快照差异视图中将一个快照与前一个快照进行比较。
在快照摘要视图中,如果拍摄了两个或更多快照,则可以通过选择差异堆大小或差异对象计数链接来查看差异快照的详细信息。
可以查看有关控制器、类型和根的差异信息。 快照差异显示添加到两个快照之间的堆中的任何对象。
此图显示快照差异中的类型视图。
![Snapshot diff view showing types Snapshot diff view showing types](http://i.msdn.microsoft.com/dynimg/IC670760.png)
在快照差异窗口中,控制器、类型和工具视图与快照详细信息窗口中的视图相同。 快照差异显示与快照详细信息相同的信息,并具有以下附加值:
“操作”。 显示当前快照中的对象和前一个快照中的对象之间的更改类型。 可能的值包括:
“未更改”。 自前一个快照以来未更改的对象显示“未更改”或空白值。 未更改的对象不会泄漏内存。
大小差异。 当前快照中对象的大小及其在之前的快照中的大小之间的差异,不包括任何引用对象的大小。
保留的大小差异。 当前快照中对象的保留的大小及其在上一个快照中的保留的大小之间的差异。 保留的大小包括对象大小加上其所有没有其他父对象的子对象的大小。 从实用的角度而言,保留大小是对象保留的内存量,因此,如果你删除对象,则你回收指定的内存量。
计数差异。 当前快照中的对象实例数和上一个快照中的对象实例数之间的差异。 此值仅显示在类型视图中。
在控制器视图和类型视图中,你可看到特定对象与 Global 对象的关系。 你可在根视图中轻松找到已知对象,而无需搜索 Global 对象树。 为此,请在控制器或类型视图中打开对象的快捷菜单,然后选择“在根视图中显示”。
在控制器视图和类型视图中,你可以通过搜索特殊标识符来筛选出数据。 若要搜索标识符,请在右上角的“标识符筛选器”文本框中键入标识符名称。 在开始键入时,不包含键入字符的标识符会被筛选出来。
由于每个视图都有其自己的筛选器,因此当你切换到另一个视图时,不会保留上一个视图的筛选器。
在控制器视图和类型视图中,下窗格包含显示共享引用的对象引用列表。 当你在上窗格中选择一个对象时,对象引用列表将显示指向该对象的所有对象。
如果需要额外的帮助来标识等效对象,请在上窗格的右上角的设置列表中选择“显示对象 ID”。 此选项将在“标识符”列表中的对象名称旁显示对象 ID(ID 将显示在所有视图中,而不只是显示在对象引用列表中)。 具有相同 ID 的对象是共享引用。
下图显示了选定项目的对象引用列表以及显示的 ID。
![Object references with displayed IDs Object references with displayed IDs](http://i.msdn.microsoft.com/dynimg/IC672717.png)
默认情况下,控制器和类型视图仅显示你在应用程序中创建的对象。 这可帮助你筛选出不需要的信息,并隔离应用程序相关的问题。 但是,有时查看由 JavaScript 运行时为你的应用程序生成的所有对象可能会很有用。
若要显示这些对象,请在窗格右上角的设置列表中选择“显示内置对象”。
诊断快照摘要与其关联的详细信息视图一起保存为 .diagsession 文件。 “解决方案资源管理器”在诊断会话文件夹中显示前几个诊断会话。 在“解决方案资源管理器”中,可以打开前几个会话或者删除或重命名文件。
performance.mark 设置一个用户标记(倒三角形),该标记在应用程序运行时显示在摘要视图中的内存关系图的时间线上。 此命令采用一个描述事件并且在内存关系图中显示为工具提示的字符串参数。 此说明不能超过 100 个字符。
如果你将这两条命令添加到应用程序中并在 JavaScript 内存分析器的外部运行应用程序,则这两条命令将引发异常。 但是,你可在使用这两条命令之前测试它们是否存在。(这两条命令在会话启动阶段的早期不存在。)若要检查是否可以安全调用 takeHeapSnapshot,请使用此代码:
当内存问题的原因时难以确定时,应使用各种视图(例如控制器和类型)查找共性,例如大小和对象计数不断增长的关联的对象和类型。
创建一个测试对象,并在 JavaScript 内存分析器视图(如控制器视图)中跟踪该对象。 例如,可以将一个极大对象附加到另一个对象以查明特定对象或组件是否已进行垃圾回收。
用Javascript自动分析数据 关键在于从不同数据源获取数据 数据分析是指用适当的统计分析方法对收集来的大量数据进行分析,将它们加以汇总和理解并消化,以求最大化地开发数据的功能,发挥数据的作用。
相关文章
- JavaScript变量、作用域及内存详解
- 理解javascript中的回调函数(callback)
- JavaScript 堆内存分析新工具 OneHeap
- JavaScript – Proxy
- JavaScript之Ajax Util
- JavaScript之字符串匹配工具[插件]
- 4类 JavaScript 内存泄露及如何避免
- 【笔记】再学JavaScript ES(6-10)全版本语法——ES8新增
- 【笔记】再学JavaScript ES(6-10)全版本语法——Iterator
- 理解JavaScript中的arguments,callee,caller,apply
- 《javascript高级编程》读书笔记(三)变量、范围和内存的问题
- javascript <a> 标签打开相对路径,绝对路径
- javascript设计模式之观察者模式
- 分析内存使用情况 (JavaScript)
- javascript实现的图数据结构的广度优先 搜索(Breadth-First Search,BFS)和深度优先搜索(Depth-First Search,DFS)
- JavaScript中的单体模式四种实现方式
- JavaScript中call和apply方法
- 37个JavaScript基本面试问题和解答
- 48 个 JavaScript 代码片段
- 理解JavaScript的柯里化