多态内存分析,UE3 内存分析器

 2023-09-23 阅读 22 评论 0

摘要:概述 C++引擎后端C#可视化前端 使用内存分析器初始设置 运行时选项前端选项 前端应用程序 1. 主菜单 选项对话框分析选项列表视图关联菜单 2. 主工具条3. 数据表现类型 A. 调用图表视图B. 独占视图C. 时间轴视图D. 调用栈历史记录E. 柱形图F. 内存位图G. 短期内存分配
  • 概述
    • C++引擎后端
    • C#可视化前端
  • 使用内存分析器
  • 初始设置
    • 运行时选项
    • 前端选项
  • 前端应用程序
    • 1. 主菜单
      • 选项对话框
      • 分析选项
      • 列表视图关联菜单
    • 2. 主工具条
    • 3. 数据表现类型
      • A. 调用图表视图
      • B. 独占视图
      • C. 时间轴视图
      • D. 调用栈历史记录
      • E. 柱形图
      • F. 内存位图
      • G. 短期内存分配
      • H. 详细视图

概述

现有的各种工具和调试技术对于跟踪您游戏的内存泄漏问题和帮助查找内存分配状况趋势都是非常有用的。其中有一个工具是内存分析器。它被分割为两部分独立的代码:引擎中的C++后端和用于查看数据的C#前端。

要想获得其它工具,请参照内存跟踪页面。

C++引擎后端

在引擎侧,存储器分配分析器是一个在基本的默认分配器之前插入的代理分配器。它捕获对Malloc/ Free/ Realloc函数的调用,当调用发生时,它会序列化每次对磁盘进行分配内存和释放内存操作的相关信息。对于Malloc/ Realloc函数来说,不管执行捕获动作的内部函数是什么,这包含一个完整的调用栈, 同时还会捕获脚本调用栈。在 Playstation3 上,malloc 分析器会捕获在 "Local"(也就是 VRAM、RSX 内存)和 "Host"(可以访问 GPU 的主要内存)上分配的内存。

为了提高效率并降低文件的内存占有量,每次分配动作产生的标记流包含了到特定调用栈的索引,这使得即使捕获很长的游戏会话中所有的分配动作的性能消耗也是非常小的。(比如,加载战争机器2中的菜单关卡,它包含了引擎初始化、启动把序列化操作,这会导致产生一个大小约50 MB字节的文件。) 它支持自动把文件分割成大约1G字节的块,从而遭遇受到文件系统和引擎限制的问题。这样的设计会使得所捕获的信息的总量对前端的内存消耗仅造成较小的影响。

请访问内存分析器 PS3了解针对平台的下载章节。

C#可视化前端

您可以在//depot/UnrealEngine3/Binaries文件夹中找到C#可视化前端,我们称其为MemoryProfiler2.exe。它支持把分配流解析为真正的自顶向下的调用图表,把数据导出到CSV文件中,并且当在控制台输入 SNAPSHOTMEMORY 时,会生成C++后端嵌入的快照的差别。

使用内存分析器

初始设置

  • 将 UnrealBuildTool BuildConfiguration.cs 文件中的 bUseMallocProfiler 更改为 true。编译并运行游戏。
  • 可以将可执行函数重新命名为其中包含 .MProf 的名字。仅适用于 Xbox360、PS3 和 Windows。
  • 如何准备进行测试的数据 
    • 当用户执行 MPROF STOP 命令并将所有需要的文件复制到目标位置后会自动在 Xbox360 上执行所有操作。
    • 在 PS3 上的情况有一点复杂,但是也没那么麻烦,在 <game>\Profiling 中执行完 MPROF STOP 后,这个文件夹中将会生成 mprof 文件。接下来您应该在这里复制一个 PS3 可执行文件,使用它可以收集统计数据。这个步骤非常重要,因为位于可执行函数中的符号通常会改变,将可执行函数随 mprof 文件一起存储是一个好的习惯。
    • 在iOS上,比如记录,文件会被保存在设备文件系统上。要获得它,只需运行IPhonePackager.exe,如果需要在命令行上指定游戏名称。按下“Other Deployment Tools(其他配置功能工具)...”按钮。选择Backup Documents(后备文档),浏览合适的ipa,然后按下“确定”。这样做会将文件复制到您的电脑的UnrealEngine3根目录中。iOS游戏的每次编译都可以在dSYM文件中生成一个新的符号集合。与PS3相似,保存一个您用于内存分析的 .app.dSym.zip文件的副本可能会是一个好主意。

运行时选项

* 在控制台输入 **`MPROF MARK`** 来忽略快照标记。 这些是游戏运行时的内存查看器可以向您显示当前的内存分配状况的时候。 您还可以在标记后面紧接着会显示在 MemoryProfiler2 中的名称,例如, **`MPROF MARK AtMainMenu`** ( **`SNAPSHOTMEMORY`** 也可以代替 **`MPROF MARK`** )。* 此类屏幕截图将会被标记为 **"Snapshot &lt;Index&gt;: &lt;Text&gt;"**
* 输入 **`MPROF STOP`** 来完成优化会话,并序列化头文件信息到一个内存分析(.mprof)文件中。当输入这个命令后将不能进行进一步的捕获跟踪。 注意: 如果没有进行这步操作,那么捕获跟踪就是没有用的,通常在您完成捕获您所感兴趣的区域时输入 **`MPROF STOP`** ( **`DUMPALLOCSTOFILE`** 是 **`MPROF STOP`** 的另一个名字)。
* 引擎还会插入一些自动的屏幕截图,这个列表包括以下内容* 当引擎在加载一个新的关卡之前开始清理过程的时候截取的屏幕截图,将会被标记为 **"LoadMap Start: &lt;LevelName&gt;"*** 当新关卡开始加载后截取的屏幕截图,将会被标记为 **"LoadMap Mid: &lt;LevelName&gt;"*** 当新关卡加载完成后截取的屏幕截图,将会被标记为 **"LoadMap End: &lt;LevelName&gt;"*** 当垃圾回收开始的时候截取的屏幕截图,将会被标记为 **"GC Start: &lt;Index&gt;"*** 当垃圾回收完成的时候截取的屏幕截图,将会被标记为 **"GC End: &lt;Index&gt;"*** 当申请加载一个新的动态加载关卡加载后截取的屏幕截图,将会被标记为 **"LevelStream Start &lt;Index>: &lt;LevelName&gt;"*** 在使之前动态加载的关卡可见后截取的屏幕截图,将会被标记为 **"LevelStream End &lt;Index>: &lt;LevelName&gt;"**

前端选项

  • 启动MemoryProfiler2.exe并在游戏的分析文件夹中打开内存分析(.mprof)文件。您可以使会使用菜单 "File - Open(文件 - 打开)" 或者键盘快捷方式"Ctrl+O"
  • 选择您想在哪个时间点进行比较,选择筛选选项然后按下Play.png Go(开始) 按钮。
  • 您也可以把当前显示的信息通过 "Export to CSV(导出到 CSV)(Ctrl+E)" 选项将其转存到文件中。
  • 脚本调用栈编码。正确的脚本函数名称现在显示在 MemoryProfiler2 应用程序的 UObject::ProcessInternal 中。如果在 native 调用栈中有多个不同的脚本调用栈,那么 只会运行最上面的脚本调用栈。在正方形框中标记脚本函数,例如, [Script] Engine.Init:GameVieportClient
  • 脚本对象类型标识。在分配一个新的 UObject 时,会记录它的类型并使其可供 MemoryProfiler2 使用。您可以查看在 UObject::StaticAllocateObject 栈帧前面的方框中所分配的对象的类型,例如 [BoolProperty] UObject::StaticAllocateObject 。它可以很好地在调用图表视图中隔开所有不同的脚本类型。
  • 自动地查找正确的标记文件。 
    • 在PC上不需要这个功能,因为在保存时已经收集了标记信息。
    • 在游戏机平台上,反而需要序列化可执行文件的名称。
    • 如果从默认的位置运行内存分析器,那么它可以找到正确的可执行文件和标记。如果内存分析器没有找到符号,那么应用程序会显示一个对话框,询问用户是否显示正确的符号所在的位置

前端应用程序

将这个章节划分为三个部分。

  1. 首先显示主菜单选项并说明它们的用途
  2. 接下来会显示主要工具栏并说明它的使用方法
  3. 最后一部分会显示其中含有视图支持的关联菜单的选项卡菜单中提供的所有视图。
  4. 这是会显示计算的数据的主要屏幕。

01MainView.png

1. 主菜单

![02FileMenu.png](02FileMenu.png) **文件** * **Open (F2)** - 会创建一个打开对话框来选择 .mprof 文件 * **Export to CSV (Ctrl+E)** - 会将分配从屏幕截图中导出到一个 CSV 文件,通过名字传递 * **Quit (Ctrl+X)** - 会关闭内存分析器应用程序
![03EditMenu.png](03EditMenu.png) **编辑** * **Find (Ctr+F)** - 会打开查找对话框,只在调用图表试图中有效,请参阅下面的 **[Find dialog](#FindDialog)** * **Find next (F3)** - 会根据查找对话框中的搜索标准查找下一个匹配项。 * **Copy highlighted to clipboard** - 会将调用图表视图中高亮显示的节点复制到剪贴板中,只有在 **"Find all(查找全部)"** 后使用时才有效 * **Unhighlight all** - 会取消高亮显示调用图表视图中的所有节点
![04ToolsMenu.png](04ToolsMenu.png) **工具** * **Options (Ctrl+O)** - 会打开选项对话框,请参阅下面的 **[选项对话框](#OptionsDialog)** * **Invert callgraph view (Ctrl+I)** - 默认情况下会禁用这个选项,请参阅下面的[调用图表视图](#CallgraphView)部分 * **Filter out Object VM functions (Ctrl+V)** - 是否过滤掉所有与 UObject 虚拟机器相关的函数,例如, **UObject::exec** 、 **UObject::CallFunction** 或 **UObject::ProcessEvent** ,默认情况下处于启用状态。要应用这些更改,您必须重新加载文件。请参阅下面的[调用图表视图](#CallgraphView)部分
![05HelpMenu.png](05HelpMenu.png) **帮助** * **Open UDN help page (F1)** - 在浏览器中打开这个页面

选项对话框

在选项对话框中,只有一个设置可以进行编辑。这是 ClassGroups 集合,一个定义调用栈过滤的类组的列表。它可以支持常规的表达式,所以设置一个单独的可以缓存您感兴趣的各种调用栈的表达式。将选项存储到文件 MemoryProfiler2.ClassGroups.xml 中,这样您就可以通过使用内置编辑器或手动编辑它。每次关闭内存分析器应用程序的时候都会写入选项。在您打开了一些应用程序实例的情况下要小心。

每个类组都包含下面的属性:

  • Name - 这个类集合的名称
  • bFilter - 在这个查询中是否包含这个类组
  • Color - 在渲染图片时要为这个组使用的颜色。
  • CallStackPatterns - 这个模式可以匹配的栈帧的列表。

CallstackPattern 包含一些其他属性:

  • OrderBias - 通过更改这个属性,您可以控制在组中如何整理模式。值越小,应用这个模式越容易。可以是负数
  • PatternOrderGroup - 可以确定模式应用的顺序的组。首先应用 Specific(特定) ,最后是 CatchAll 。 
    • Specific - 需要首先进行计算的指定模式,例如,Texture Pool(贴图池)
    • SubPools - 适用于那些表示您希望脱离其他内容单独考虑的内存分配组的模式。例如,从诸如 PhysX 这样的中间件中分配的内存
    • General - 更加常见的模式,例如,Animations、Shaders 等等,大多数模式属于这个类别中
    • CatchAll - 可以接收到更明确的组所丢失的其他调用栈的捕获所有组,例如,Misc UObjects
  • StackFramePattern - 这个模式可以匹配的栈帧的列表。
所有列出来的模式必须与要匹配的模式的调用栈中的栈帧匹配。 栈帧必须与帧模式的顺序一致,但是它们不需要是连续的。 例如,考虑这个 Pattern(模式): {"A::Function1()", "B::Function2()"} 下面的调用栈与它匹配: Blah() A::Function1() Blah2() Blah3() B::Function2() Blah4() 下面的调用栈不匹配: B::Function2() A::Function1() nor does this: Blah() A::Function1() Blah2() 最多调用栈模式将只会有一个单独的帧模式,但是允许多个帧可以更加灵活。
  • UseRegexes - 如果这个选项为 true,这个选项会插入所有 StackFramePatterns 作为常规表达式

07ToolsOptions.png

分析选项

有些数据结构会占据大量内存。这里有一个隐藏的选项对话框,它可以让您禁用特定功能以保存内存。ProfilingOption 会调用这个对话框,现在通过 GUI 无法访问它,默认情况下它会启用所有选项。如果您发现这个内存分析器应用程序在加载一个大的概要文件时内存溢出,那么您应该试着更改选项或者使它可以通过 GUI 使用。

98ProfilingOptions.png

列表视图关联菜单

在非独占视图、柱状图视图、内存位图视图和短期内存分配视图中,其中列表视图包含用户可以选择一排然后只将选中的这一排全部调用栈复制到粘贴板中的调用栈。

97ContextMenuCopy.png

2. 主工具条

18MainToolBar.png

19MainToolBarChanged.png

ExclamationMark.png " 位于这个选项的旁边表示该选项已经更改过,您必须点击 Play.png Go(开始) 刷新数据。 对于某些视图一些过滤选项可能无法使用(灰掉了),例如在加载除 PS3 mprof 数据之外的任何数据时的 "Pool Filter(池过滤器)" 。

![08ToolDiffStart.png](08ToolDiffStart.png) **比较开始** 这个组合框包含所有从 mprof 文件中读取的屏幕截图的数组。 用来选择比较的开始截图。 开始截图是一个已经完成的虚拟截图。 默认: **Start**
![09ToolDiffEnd.png](09ToolDiffEnd.png) **比较结束** 这个组合框包含所有从 mprof 文件中读取的屏幕截图的数组。 用来选择比较的结束截图。 默认: **End**
![10ToolSortBy.png](10ToolSortBy.png) **按照大小分类** 设置调用图表视图/独占视图中的节点的分类 * **Sort by Size** - 按照内存分配的大小对节点进行分类,默认情况下会启用这个选项 * **Sort by Count** - 按照内存分配的数量对节点进行分类
![11ToolAllocations.png](11ToolAllocations.png) **激活的内存分配** 设置将用于在调用图表视图、独占视图和柱形视图中填入数据的指定调用栈列表 * **Active Allocations** - 设置激活的内存分配列表(这个包括只有在截图的结束部分才会提供内存分配),默认情况下会启用这个选项 * **Lifetime Allocations** - 设置声明周期内存分配列表(这包括在截图的开始和结束部分之间的所有内存分配,即使是已经被释放的内存)
![12ToolContainers.png](12ToolContainers.png) **隐藏 Container** 设置用于通过函数名称隐藏 container 的选项。将 container 定义为具有以下名称的函数: operator new<, operator<<, >::, FString::operator=, FStringNoInit::operator=, FString::FString, FBestFitAllocator::, FHeapAllocator:: * **Hide Containers** - 启用通过函数名称隐藏 container,默认情况下会启用这个选项 * **Show Containers** - 禁用通过函数名称隐藏 container
![13ToolFiltering.png](13ToolFiltering.png) **过滤进入** 设置过滤类型 * **Filter Out** - 根据过滤、文本过滤和池过滤的类启用过滤出来 * **Filter In** - 根据过滤、文本过滤和池过滤的类启用过滤进入,默认情况下会启用这个选项
![14ToolClassesToFilterSmall.png](14ToolClassesToFilterSmall.png) **要过滤的类** 用于缩小结果范围的常用类组的列表。每次用户更改选项对话框中的 **ClassGroups** 集合时都会更新这个菜单。默认情况下会检查所有类。 * **All** - 会勾选所有类组 * **None** - 会取消勾选所有类组
![15ToolTextFilter.png](15ToolTextFilter.png) **文本过滤** 启用通过键入的文本过滤数据,默认情况下为空。 键入一个文本启用基于文本的过滤功能。按下回车键或者点击 ![Play.png](Play.png) **Go(开始)** 刷新数据 / 开始进行处理。
![16ToolPoolFilter.png](16ToolPoolFilter.png) **池过滤** __(这个选项只适用于 PS3)__ 会启用通过内存池进行过滤,默认情况下会勾选所有池 * **Main** - 主要内存池 * **Local (GCM)** - 本地视频内存池(RSX 内存) * **Host (Default)** - 主机内存池(RSX 可以访问的内存) * **Host (Movies)** - 用于存储视频的主机内存池 * **All** - 选择所有内存池 * **None** - 不选择任何内存池
![17ToolGo.png](17ToolGo.png) **Go(开始)** 开始处理选中的截图和视图的数据 * ![Play.png](Play.png) **Go** - 当前截图是最新截图 * ![PlayRed.png](PlayRed.png) **Go** - 当前截图需要刷新数据,这个按钮只有在您在主工具条中更改了一些选项后才会改变 __已知问题:__ * __如果您切换到另一个选项卡,那么在刷新后 ![Play.png](Play.png) **Go** 按钮将仍然保持为绿色__

3. 数据表现类型

A. 调用图表视图

会显示由唯一的调用栈统计的内存分配情况。将视图分为两个树形结构,第一个树形结构包含删减的调用栈,第二个树形结构包含所有的调用栈。删减的调用栈通常会出现在那些调用栈很长的脚本调用栈上。沿着树结构向下的每个节点包含了内存分配的概要。
调用图表视图还具有搜索功能。用户可以使用与其他应用程序相似的功能进行搜索,包括常规的表达式支持以及一个可以突出显示您的搜索查询中的所有实例并通知您它们增加了多少内存的 Find All(查找全部) 函数。这样做,或者用户可以根据文本过滤获得相同的结果。

![06FindDialog.png](06FindDialog.png) ![22FindAllResults.png](22FindAllResults.png)

当您在节点上右击的时候,会显示关联菜单。这个菜单包含以下选项:

  • Reset Parent - 将父代函数重新设置为默认状态,然后重新解析这个文件,这样就没有应用过滤
  • Set Parent - 设置当前选中的树节点并重新解析以应用这个过滤
  • View History - 查看所有从这个节点继承的调用栈的历史记录,后文中将会显示更多示例
  • Copy Function to Clipboard - 将函数名称复制到剪贴板
  • Copy Size to Clipboard - 将大小复制到剪贴板
  • Expand All / Collapse All - 展开所有 / 收起所有 节点, 这项操作可能需要花一段时间才能完成

UGearEngine::Tick 的调用图表视图中包含可见的关联菜单。
20CallGraphView.png

用户现在可以在调用图表视图中倒置调用栈,这样它就会从上到下显示它们而不是从下到上地显示。这样做有时候有利于查找通过很多不同的地方调用的底层函数的内存分配情况。它的选项在 Tools(工具)菜单中, "Invert callgraph view(倒置调用图表视图)(Ctrl+I)" 。请参照下面的截图:
21CallGraphViewInverted.png

这是一个脚本调用栈的示例,其中启用了过滤出 UObject 虚拟机器函数的功能。勾选 "Tools Filter out Object VM functions (Ctrl+V)"
00FilterObjectVMFunctionsEnabled.png

与上面的示例相同,但是禁用了过滤出 UObject 虚拟机器函数的功能。取消勾选 "Tools Filter out Object VM functions (Ctrl+V)"
01FilterObjectVMFunctionsDisabled.png

B. 独占视图

会显示由组汇集的内存分配情况。这个视图由两个主要列表视图组成,左边是一个通过唯一调用栈分组的内存分配列表,右边是一个完整的调用栈信息,其中包含每一帧的文件名和行号。下面是有关左边的列表视图列标题的详细信息:

  • Size (KByte) - 内存分配的大小(以千字节为单位)
  • Size (%) - 内存分配大小占总大小的百分数
  • Count - 内存分配的数量
  • Count (%) - 内存分配数量占总内存分配数量的百分比
  • Group Name - 这个内存分配所属的组的名称
  • Function Name - 调用栈中最上面的函数的名称

您可以通过在列标题上点击挑出一个特定的列。排列顺序由分类箭头指定。
23ExclusiveView.png

C. 时间轴视图

这个视图会显示整个运行过程或者选中的截图的内存分配历史记录。只是一个呈栈形排列的图表,下面的表格将会对用户在图标上可以找到一些系列进行说明:

Allocated Memory(分配的内存)

所有平台

The total amount of memory used by the game(供游戏使用的内存的总量)

Image Size(图片大小)

Xbox360, PS3

加载的可执行函数的大小,栈、静态和全局对象大小

OS Overhead(OS 消耗)

Xbox360

操作系统的消耗

Virtual Used(使用的虚拟内存)

所有平台

应用程序虚拟内存正在使用的内存分配

Virtual Slack(虚拟闲置)

所有平台

OS/分配器中的内存分配,但是不供应用程序使用

Virtual Waste(虚拟浪费)

所有平台

掌控的分配器中的调整浪费,此外还会记录持续的消耗

Physical Used(使用的物理内存)

所有平台

应用程序物理内存正在使用的内存分配

Physical Slack(物理闲置)

所有平台

OS 中的内存分配,但是不供应用程序使用

Physical Waste(物理浪费)

所有平台

掌控的分配器中的调整浪费,此外还会记录持续的消耗

Host Used(使用的主机)

PS3

供应用程序使用的主机内存

Host Slack(主机闲置)

PS3

分配的主机内存,但是不可以供应用程序使用

Host Waste(主机浪费)

PS3

由于内存分配的调整而浪费的主机内存

30TimeLineView.png

用户还可以添加自定义标记点。要进行这项操作,您需要在您感兴趣的地方点击这个图片,然后只要重新加载了当前的 mprof 文件后,这些自定义标记点就会被添加到这个截图中,描述内容为 "Unnamed snapshot allocations: <AllocationCount>"
31TimeLineCustomMark.png

D. 调用栈历史记录

调用栈历史记录选项卡会显示调用栈内存分配的完整历史记录,甚至通过 reallocs 方法追踪它。例如,如果您具有一个名为 malloc 的调用栈,然后是另一个稍后会将同一个内存分配重新分配一个较大的尺寸的调用栈,在这种情况下如果您显示了第一个调用栈的历史记录,那么它会包括重新分配的内存,您将可以看到这个图表行在这一点上升,而不是下降到 0。您可以显示调用栈的整个组的历史记录,而且它会将所有图标累加在一起。它对于找到那些使用截图可能无法检查到的顿卡或者是侦查泄露非常有用(它看起来是一个不断攀升始终不会下降的行)。

注意,如果您想要查看多个调用栈的历史记录(独占视图、短期内存分配视图、内存位图视图),那么这个应用程序必须在可以显示历史记录之前将将它们所有的尺寸大小图标都累加在一起,这个过程可能需要几秒钟,如果调用栈很多的话,可能需要更长时间。

在这个应用程序中到处都是各种右击菜单,其中的 "View History(查看历史记录)" 选项可以让您查看特定的调用栈。参阅下面表格中每个支持的视图的示例,这样才能知道如何得到它们:

![40CallstackHistory_CallgraphView.png](40CallstackHistory_CallgraphView.png) **[调用图表视图](#CallgraphView)** 它会显示从这个您右击菜单项 **"View History(查看历史记录)"** 的节点继承而来的所有调用栈的历史记录
![41CallstackHistory_ExclusiveView.png](41CallstackHistory_ExclusiveView.png) **[独占视图](#ExclusiveView)** 您可以选择多个调用栈
![42CallstackHistory_Histogram.png](42CallstackHistory_Histogram.png) **[柱形视图](#HistogramView)** 您可以从这个主菜单栏 (Local/Video) 或者从详细的菜单栏中选择一个栏。有时这些栏非常小,点击它们比较困难无法做到,所以您可以在 **"Classes to Filter(要过滤的类)"** 下拉列表中右击类组,这样就可以选中它们啦!
![43CallstackHistory_MemoryBitmap.png](43CallstackHistory_MemoryBitmap.png) **[内存位图视图](#MemoryBitmap)** 您可以选择内存区域,并且在这个区域内已经执行了多个内存分配,通过列表视图 **"Allocation History(内存分配历史记录)"**
![44CallstackHistory_ShortLivedAllocation.png](44CallstackHistory_ShortLivedAllocation.png) **[短期内存分配视图](#ShortLived)** 您可以选择多排
![45CallstackHistory_ClassesToFilter.png](45CallstackHistory_ClassesToFilter.png) **要过滤的类** 您可以从现实的类组列表中选择一个类或使用 **"All(全部)"** 菜单选择全部,但是要显示所有调用栈的调用栈历史记录可能需要一个多小时的时间。

选择 "View history(查看历史记录)" 后,您将会看到下面的对话框,其中还会显示进度条。如果有时候您需要只是历史记录的开头部分,或者如果您意外关闭了"View History(查看历史记录)" ,您可以随时取消这项操作。
46CallstackHistory_Progress.png

带有完全处理的图片的调用栈历史记录选项卡看起来像下面的画面一样,X 轴为内存分配的动态加载位置。绿色条    表示垃圾回收使用的时间。蓝色条    表示永久性关卡加载使用的时间。这个视图的根据菜单包含以下选项:

  • Frames - 勾选后可以将 X 轴单位更改为帧
  • Allocations - 勾选后可以将 X 轴单位更改为内存分配的动态加载位置,默认情况下启用这个选项
  • Show Complete History - 勾选后显示完整的历史记录,而不会显示所选中的屏幕截图之间的范围
  • Show Snapshots - 勾选后会显示屏幕截图信息,默认情况下会启用这个选项
  • Reset zoom - 将变焦重新设置为默认值
  • Zoom H: V: - 当前水平和垂直焦距值,要改变水平焦距值,请按下 Control 键同时使用鼠标滑轮,要改变垂直焦距,请按下 Shift 键同时使用鼠标滑轮,最小和默认焦距因数为 1,最大值为 10

47CallstackHistory_Graph.png

X 轴为内存分配的帧位置的图片。
48CallstackHistory_GraphFrames.png

E. 柱形图

柱形图选项卡会将两个内存条显示为列(实际上只有 PS3 有两个内存条,其他平台只使用第一个内存条)。将这两列划分为条,划分的一句是在选项对话框中定义的类组。当您点击一个条时,第三列将会填入在这一列中所有调用栈的细目。当您在这个新的列中点击一个条时,您可以在右边的列表框中看到这个调用栈,在"Details(详细信息)" 字段中看到一些信息。您可以在您的键盘上使用 "up(向上)" 和 "down(向下)" 箭头键在柱形条之间移动。

在前面两列中的底部条,填充的颜色为紫色,由取消组合的调用栈组成。对它使用特殊的 Ungrouped(取消组合) 的组合。如果该区域特别大 - 那意味着您可能需要分配它的某些调用栈来自定义组合。

50Histogram.png

F. 内存位图

内存位图选项卡是非常明显的。不推荐使用 Win64 概要文件,因为它们会在靠近空间底部的地方分配一些内存,然后在靠近空间顶部的地方分配一些,所以默认情况下,它最终实际上都是缩小的视图。最初它可能是空白的,但是如果您仔细看,您应该会在底部和顶部看到一些像素。32 位平台更加合情合理。点击这个位图会为您提供在这个地址上所有内存分配的完整历史记录,然后吐出显示最近的历史记录。

注意,图片底部的红紫色区域是内存空间结束的地方。位图中每个像素的字节数是正数,这个位图的结尾部分始终都会有一些超出所选内存范围的像素。将它们着色为深紫红色   

这个视图的根据菜单包含以下选项:

  • Reset selection - 清除选项
  • Reset zoom - 将变焦重新设置为默认值
  • Zoom to Rows - 勾选后会启用这个选项,那么会使用鼠标拖拉将要进行缩放的区域。缩放功能会使用一个栈,这样每次您放大它的时候会将您之前的缩放等级添加到这个栈中。您可以使用 "Undo Last Zoom(取消最后一次缩放)" 按钮返回到之前的缩放等级
  • Undo Last Zoom - 取消最后一次缩放操作
  • 显示网站点击热地图 / 显示内存地图 
    • 'Show Heat Map(显示网站点击热图)' 会显示每个网址的“受欢迎”程度,它的依据是在给定空间所出现的内存分配量。如果地址颜色更接近于白色,那么表示使用它的频率要比其他地址多。
    • 'Show Memory Map(显示内存图)' 会显示标准内存位图。取消勾选启用这个选项。
  • Memory space - 会显示可视内存区域的内存范围
  • Space size - 会显示可视内存区域的内存空间(以字节为单位)
  • Allocated memory - 会显示在可视内存区域中分配的内存量

默认内存位图视图
60MemoryBitmap.png

启用的网站点击热图模式
61MemoryBitmap_HeatMap.png

G. 短期内存分配

短期内存分配会显示在进行分配后不久就被释放的内存分配,这可能会引发性能和碎片问题。下面是有关左边的列表视图列标题的详细信息:

  • 0 Frames - 在同一帧内释放的内存分配(包括内存再分配)的数量
  • 0 Frame Count - 其中包含在同一帧上释放的内存分配的唯一帧的数量
  • 1 Frame - 在接下来的帧上释放的内存分配的数量
  • Longest Run - 帧的最长不间断运行,其中调用栈会释放它在前一帧上生成的内存分配
  • Run Avg Alloc - 会显示最长运行的平均内存分配大小(以字节为单位)

这个过程需要一段时间,所以准备好在按下 Play.png Go(开始) 后要等待大约一分钟

您可以通过在列标题上点击挑出一个特定的列。排列顺序由分类箭头指定。
80ShortLivedAllocations.png

H. 详细视图

会显示所选屏幕截图标记的详细信息。Start(开始) 会显示开始屏幕截图中的统计数据, End(结束) 会显示结束屏幕截图中的统计数据,而 Diff(区别)会显示 End(结束)-Start(开始) 之间的区别。测量值项中的大多数统计数据只受 PS3 上的 mprof 文件支持。一些其他元素也可能是 0,这种情况会在使用了没有统计数据的 Test(测试)版本采集数据时发生。

已知问题:

  • 当前和已经过去的时间不是严格正确的,使用存储的 delta 计算这些值,而不是使用当前全局时间

90DetailsView.png

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/2/92532.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息