分析性能分析器跟踪记录
Investigate common startup and runtime performance issues by analyzing Profiler traces.
阅读时间9 分钟最后更新于 1 个月前
对应用程序进行性能分析时,可能会遇到一些常见问题。本页概述了如何调查一些常见性能问题的原因。
解析启动跟踪
在查看启动时间的跟踪记录时,需要关注两个关键方法: 和 。这两个方法是项目的配置、资源和代码可能影响启动时间的主要原因。
UnityInitApplicationGraphicsUnityLoadApplication**注意:**应用程序的启动时间因平台而异。在大多数平台上,启动发生在启动画面出现时。

在 iOS 设备上运行的 Unity 项目示例的 Instruments 跟踪记录
在上面的截屏(在 iOS 设备上运行的 Unity 项目示例的 Instruments 跟踪记录)中,在特定于平台的 方法中,请注意 和 方法。
startUnityUnityInitApplicationGraphicsUnityLoadApplicationUnityInitApplicationGraphicsUnity 的资源系统在其数据中包含了项目 文件夹中 文件夹中的每个资源文件。其中包括 文件夹的子文件夹中的所有文件。因此,初始化资源系统所需的时间与应用程序项目的 文件夹中的文件数量呈正相关关系。
AssetsResourcesResourcesResourcesUnityLoadApplicationMonoBehaviourAwake这就意味着,如果在项目的第一个场景中的 回调中存在任何执行时间很长的代码,那么该代码可能会导致项目的初始启动时间的延长。解决此问题的方法是删除这些运行速度慢的代码,或者在应用程序生命周期的其他地方执行该代码。
Awake解析运行时跟踪
对于在初始启动时间之后的性能分析跟踪记录,最需要关注的是 方法。这是 Unity 的主循环,该循环中的代码每帧运行一次。
PlayerLoop
Unity 项目示例的 Instruments 跟踪记录
上面的截屏说明了 中几种对性能影响最大的方法。注意: 中的方法的名称可能因 Unity 版本而异。
PlayerLoopPlayerLoopPlayerRenderBaseBehaviourManagerCommonUpdateMonoBehaviour- 调用
CommonUpdate<UpdateManager>回调Update - 调用
CommonUpdate<LateUpdateManager>回调LateUpdate - 如果已勾选物理系统,则 调用
CommonUpdate<FixedUpdateManager>FixedUpdate
通常情况下, 是最适用于检查的方法族,因为它是 Unity 项目中运行的大多数脚本代码的入口点。
BaseBehaviourManager::CommonUpdate<UpdateManager>还有其他几种方法可用于检查:
- 如果项目使用 UGUI 系统,将调用多个不同的回调。其中包括 Unity UI 的批量计算和布局更新;这两种操作是
UI::CanvasManager出现在性能分析器中的最常见原因。CanvasManager - 运行协程。
DelayedCallManager::Update - 运行 PhysX 物理系统。这主要涉及运行 PhysX 的内部代码。当前场景中物理对象(例如
PhysicsManager::FixedUpdate和Rigidbody)的数量会影响 PhysX 的内部代码。基于物理系统的回调也会出现在此处,例如Collider和OnTriggerStay。OnCollisionStay
如果项目使用 2D 物理系统,那么会在 下显示为一组相似的调用。
Physics2DManager::FixedUpdate解析脚本方法
在使用 IL2CPP 交叉编译的平台上调用脚本时,应查找包含 对象的跟踪行。这表示 Unity 的内部原生代码转换到脚本运行时以便执行脚本代码。**注意:**从技术上讲,Unity 通过 IL2CPP 运行 C# 代码后,该代码也会成为原生代码。但是,这种交叉编译后的代码主要通过 IL2CPP 运行时框架来执行方法,与手写的 C++ 不太一样。
ScriptingInvocation
Unity 项目示例的跟踪记录
在上面的截屏中,嵌套在 行下的方法是 Unity 每帧执行一次的交叉编译的 C# 脚本的一部分。
RuntimeInvoker_Void跟踪行的名称是原始类的名称,后跟下划线和原始方法的名称。对于此跟踪记录示例,可以看到 、 和其他几个 方法。这些是 中常见的标准 Unity 回调。
EventSystem.UpdatePlayerShooting.UpdateUpdateMonoBehavioursUpdate展开这些方法后,可以查看其中哪些方法消耗了 CPU 时间。这包括项目中的其他脚本方法、Unity API 和 C# 库代码。
上面的跟踪记录显示, 方法每帧对整个 UI 进行一次光线投射。此方法检测是否有任何悬停的触摸事件或是否激活了任何 UI 元素。迭代所有 UI 元素并测试鼠标的位置是否在UI 元素的边界矩形内的方法属于资源密集型方法。
StandaloneInputModule.Process资源加载
还可以在 CPU 跟踪记录中识别出资源加载记录。标识资源加载的主要方法是 。此方法将二进制数据流通过名为 的方法从文件连接到 Unity 的序列化系统中。 方法位于所有资源类型(例如纹理、MonoBehaviour 和粒子系统)上。
SerializedFile::ReadObjectTransferTransfer
场景加载的跟踪记录
上面的截屏是 Unity 加载场景时的跟踪记录。加载场景时,Unity 会读取并反序列化场景中的所有资源,如对 下各种 方法的调用所示。
SerializedFile::ReadObjectTransfer如果在运行时看到性能不稳,并且性能跟踪记录显示 使用了大量时间,则意味着资源加载降低了帧率。**请注意:**当 、 或 AssetBundle API 请求同步进行资源加载时, 通常会出现在主线程上。
SerializedFile::ReadObjectSceneManagerResourcesSerializedFile::ReadObject为解决此类性能不稳的问题,可以使资源加载异步进行(将繁重的 调用移至工作线程),或预加载某些繁重资源。
ReadObject在 Unity 克隆对象(在跟踪记录中以 方法表示)时也会出现 调用。如果在 调用下出现了对 的调用,则表示 Unity 不是从存储中加载资源。相反,Unity 将旧对象的数据传输到新对象。为此,Unity 会序列化旧对象,并将结果数据反序列化为新对象。
CloneObjectTransferCloneObjectTransfer