使用Instruments进行性能探查

2016年02月15日 13:49 0 点赞 0 评论 更新于 2025-11-21 19:49

在为企业提供技术支持服务的过程中,我们接触过众多iOS项目。在每个iOS开发阶段,开发者们常常会遇到这样的情况:一边运行游戏,一边疑惑“这东西怎么运行得这么慢?”实际上,有不少出色的性能分析工具集,今天我们要介绍的Instruments便是其中的佼佼者。

准备工作

要使用Instruments或其他XCode调试工具,您需要构建一个以iOS为目标的Unity项目,同时取消勾选“Development Build”以及“Script Debugging”选项。之后,使用XCode以Release模式将生成的XCode项目编译并发布到已连接的iOS设备上。

启动探查

启动Instruments(可通过长按Play按钮,或选择“Products > Profile”),然后选择“Time Profiler”。接着选择要探查的应用,并按下红色的“Record”按钮,探查过程便会启动。此时,iOS设备上会运行已连接Instruments的应用,“Time Profiler”将自动记录远程传回的信息,这些信息在Instruments的时间线上以蓝色折线图呈现。

探查结果分析

调用树结构

Instruments窗口的详细区域会列出一系列方法调用,每个最顶级的方法调用代表应用中的一个线程。通常,main方法备受关注,因为它包含了所有托管代码。展开main方法后,会出现一个庞大的方法调用树,其主要分支通常为以下两种:

  • [startUnity] 以及 UnityLoadApplication(这些方法名有时会全大写显示)。[startUnity] 包含了初始化Unity引擎所需的全部时间,值得重点关注。在它下面是UnityLoadApplication方法,启动时间探查需在此方法之后进行。
  • PlayerLoop

寻找性能热点

当对应用进行一段时间的探查后,暂停Profiler并展开调用树。您会发现左栏以毫秒为单位的时间值沿树状结构向下递减。您需要寻找那些上下差值巨大的时间点,这些就是性能热点。根据这些热点返回对应代码,就能找到时间消耗的原因。这个原因可能是必要的操作,也可能是项目中遗留的陈旧代码,具体情况因人而异。是否解决以及如何解决这个问题,完全取决于您对代码的了解程度。

查找分散的性能损耗点

Instruments还能用于查找分散的性能损耗点,即那些单独来看时间消耗不大,但在代码多处不断消耗少量时间的点。具体操作如下:在Instruments的Call Tree窗口右上方的符号搜索框中输入部分或完整的函数名。如果探查对象是游戏,可展开PlayerLoop并收起其下的其他方法。某个特定操作消耗的总毫秒数可通过将PlayerLoopUnityLoadApplication上的总时间减去self栏中对应的毫秒数来粗略估算。

以下是一些常见需要查找的方法:

  • “Box(”、“box” 以及 “box”:这些代表正在发生C#值装箱操作,大多数装箱实例可轻松修正。
  • “Concat”:字符串连接操作通常可进行简单优化。
  • “CreateScriptingArray”:所有返回数组的Unity API会分配数组的新副本,应减少对这些方法的调用。
  • “Reflection”:反射操作速度较慢,可通过此方法预估反射上的时间损失,并尽量避免使用。
  • “FindObjectOfType”:用于定位重复或不必要的FindObjectOfType调用,或其他已知的慢速Unity API。
  • “Linq”:根据时间损耗决定是否创建或移除Linq查询,建议将热点对象替换为手工优化的方法。

内存使用率探查

Instruments除了进行CPU时间探查,还可用于探查内存使用率。Instruments的“Allocations”探查器提供了两个可显示应用程序详细内存使用率的探针:

  • “Allocations”探针:能检查特定时间段内驻留于内存中的对象。
  • “VM Tracker”探针:可监视脏内存堆大小,脏内存堆是iOS决定是否强制关闭应用的主要依据。

当在Instruments中选择“Allocations”探查器时,这两个探针会同时运行。同样按下红色的“Record”按钮开始探查。

要正确设置“Allocations”探针,需确保Instruments右边Detail选项卡上的以下设置正确:

  • 确保“Display Settings”(中间选项)下的“Allocation Lifespan”设为“Created & Persistent”。
  • 确保“Record Settings”(左侧选项)勾选“Discard events for freed memory”选项。

“Allocations”探针的默认视图“Statistics”是诊断内存行为的最佳工具,它以时间线形式显示。使用推荐设置时,图表上会实时显示代表时间及内存分配程度的蓝色线条。通过该图表,您只需简单重复测试场景,就能监控长时间占用或泄露的内存,确保每次运行之间没有蓝线产生。

“Call Tree”是另一个有用的视图,它能显示发生内存分配操作的代码行以及该代码行负责的内存量。例如,您可能会发现大约25%的内存使用量由着色器消耗,由于这些着色器位于加载线程中,它们很可能是应用启动时加载的与默认Unity项目捆绑的标准着色器。

当定位到热点位置后,后续操作需根据项目实际情况决定。

来源:Unity官方平台

作者信息

洞悉

洞悉

共发布了 3994 篇文章