5.Unity性能分析工具-CPUUsage
5.1 知识点
CPU Usage是什么
CPU Usage(CPU 使用率)是 Unity Profiler 里最常用、也最“顶用”的模块之一。它会把每一帧 CPU 花了多少时间拆开,并按类别(脚本、物理、动画、渲染准备、GC……)统计出来,方便你快速判断瓶颈在哪里。
游戏开发里常见的 CPU 开销来源:
- 脚本逻辑:我们写的 C# 代码(Update、协程、各种管理器逻辑等)
- 物理系统:Unity 内置物理引擎(碰撞检测、刚体模拟等)
- 动画计算:动画状态机、骨骼动画混合采样、蒙皮等
- 渲染准备:剔除、排序、构建绘制命令、提交渲染命令等
- 资源管理与加载:加载 AssetBundle、场景、纹理、网格、材质等元数据
- GC(垃圾回收):托管堆回收造成的卡顿/抖动
- UI 系统:GUI/UGUI 的布局计算、事件派发、批处理与渲染数据准备
- 导航与寻路
- 音频处理
- 输入检测
- 网络通讯
- 屏幕后处理(C# 部分)
- ……以及一些未分类的引擎底层开销
一般项目出现卡顿、掉帧问题,第一时间都可以先从 CPU Usage 开始排查。
CPU Usage中各参数功能的含义和作用
CPU 使用率 分析窗口

这里会用不同颜色把每一帧的 CPU 时间拆开,你可以很直观地看到“到底是谁在吃时间”。常见分类含义如下:
- 渲染准备(Rendering):准备渲染命令的时间,比如
Camera.Render、生成 DrawCalls 的阶段 - 脚本(Scripts):执行 C# 脚本的时间(如
Update、Start、协程等) - 物理(Physics):物理计算时间,包括碰撞检测、刚体模拟(2D/3D)
- 动画(Animation):动画相关时间(
Skinned Mesh Renderer、Animation、Animator等) - 垃圾回收(GarbageCollector):GC 产生的回收时间,常见为“抖一下/突然卡一下”
- 垂直同步等待(VSync):等待垂直同步的时间(有时会表现成“帧被卡住”)
- 全局光照(Global Illumination):实时全局光照相关 CPU 开销
- UI:UI 相关(Canvas 更新、重建、批处理、渲染数据准备等)
- 其它(Others):不属于以上分类的内容,比如编辑器自身开销、未分类任务、引擎底层消耗等

- 竖线上的数值:当前选中帧里,各颜色块对应的耗时(单位 ms)
- 横向参考线:
66ms(15FPS)33ms(30FPS)16ms(60FPS)- 用来快速判断:这一帧是不是已经超过目标帧率的“时间预算”
模块详细信息面板

注意:
- TimeLine 视图可以显示所有线程的性能数据
- Hierarchy 视图一次只显示一个线程的数据,需要手动切换线程
TimeLine(时间线视图):

显示特定帧的时间细分信息,以及该帧长度的时间轴。
- 显示方式:横向时间轴,按线程显示每个函数的开始与持续时间,精确到每个调用片段
- 结构:一个横轴 = 一帧时间,纵轴 = 不同线程(Main Thread、Render Thread 等)
- 用途:
- 看每个函数调用在时间上所占的位置和长度
- 清楚显示函数调用之间是否并发/串行
- 非常适合排查 主线程阻塞、线程切换耗时 等问题
Hierarchy(层级视图):

按时间数据的内部层级结构对这些数据分组
- 显示方式:以调用栈的方式展示函数调用结构,从根函数一路展开
- 结构:每一行是一个函数调用,子函数缩进在其下方
- 用途:
- 快速发现“树顶函数”调用最多的分支
- 定位哪一个函数调用下挂着最多性能开销
Inverted Hierarchy(倒置层级视图):

按分析器标记对样本进行分组,并用倒置的样本堆栈显示它们。
- 显示方式:将调用树倒过来看,从最底层函数反推“是哪些函数调用了它”
- 用途:
- 用于分析一个具体函数被谁频繁调用
- 常用于调试“这个慢函数为什么会被频繁触发”的问题
- 和 Hierarchy(层级视图)是互补关系
Raw Hierarchy(原始层级):

以类似于发生计时的调用栈的层级结构显示时间数据
- 显示方式:不做任何聚合和折叠处理,展示完整原始采样数据
- 用途:
- 查看完整调用链
- 更贴近采样器采集的真实结构,但可能非常冗长复杂
Hierarchy(层级视图)
常用开关与入口:
Live:开启后显示当前帧/选定帧的信息;关闭后只有选中某一帧时才显示Main Thread:当前查看的线程(可在这里切换要分析的线程)- 搜索栏:按函数名搜索
关键列(读数):
Total:当前函数(包含子函数)占该帧总时间的百分比- 常用来判断:这一整条调用链值不值得继续深挖
Self:函数自身占用的百分比(不包含子函数耗时)- 例子:某函数
Total很高,但Self只有0.2%,说明真正耗时在它调用的子函数里
- 例子:某函数
Calls:该函数在这一帧的调用次数- 调用次数很高时,往往要注意是不是不必要的重复调用
GC Alloc:该函数在这一帧触发的 GC 分配量(单位 Byte)- 明显偏大时,通常意味着频繁
new/ 字符串拼接 / 临时容器等,后面可能引发 GC 卡顿
- 明显偏大时,通常意味着频繁
Time ms:当前函数(含子函数)在该帧的总耗时(毫秒)Self ms:函数自身耗时(毫秒,不包含子函数)
两个常见“根节点”:
EditorLoop:编辑器主循环(非 Play 模式),面板更新、UI 重绘、资源导入、编译、插件逻辑等都会在这里发生PlayerLoop:游戏运行时主循环(Play 模式),脚本、渲染、物理、输入、协程、动画等基本都挂在这条链上
观察建议:
- Total 高但 Self ms 低:慢在子函数,继续展开下层
- Self ms 高:函数本身可能有问题(密集计算/阻塞)
- Calls 很高:是否有不必要的循环调用?考虑合并/缓存
- GC Alloc 明显:是否频繁创建对象/字符串?后面容易触发 GC
额外信息下拉框
这里控制右上角的“额外信息”展示方式:
No Details:不显示额外信息,只看函数树 + 时间/GC/调用次数等Related Data:显示与当前样本相关的上下文信息(Markers、线程关联、调用位置上下文等),用得相对少,但分析线程协作时会有帮助Calls:显示该样本的调用来源与它调用的其他函数- 常用于追溯“这个函数到底是被谁调用出来的”
使用建议:
- 只关心耗时 → 用
No Details - 想找调用源头 → 用
Calls - 想看线程/上下文相关信息 → 用
Related Data
TimeLine(时间线视图)
TimeLine会按线程把一帧里的时间切片铺开。常见线程含义:Main Thread:主线程,跑大部分游戏逻辑(脚本、物理、渲染提交等)Render Thread:渲染线程,把渲染命令提交给 GPU(通常异步)Job:Job System 的多线程任务(并行计算)Loading:资源加载相关(异步读取纹理/场景/AssetBundle 等)Scripting Threads:非主线程的 C# 脚本线程(例如自定义后台线程)- ……等等
Live:开启后显示当前帧/选定帧信息;关闭后只有选中某一帧才显示彩色横条块:
- 每条代表一个采样事件(函数/操作)
- 宽度 = 耗时,颜色 = 模块类别(Scripts/Rendering 等)
- 悬浮可查看名称与耗时(例如
Profiler.FlushCounters (0.046ms))
Show Full Scripting Method Names:显示完整的脚本方法名称Show Flow Events:显示线程间异步任务的调用路径(比如 Job 与 Main Thread 的联系线)
使用建议:- 多线程性能分析(例如:Job 执行耗时)
- 追踪跨线程任务顺序(例如:资源加载 → 渲染)
- 视觉化查看整帧分布结构
CPU Usage对于我们的意义
问题:看 CPU Usage 到底能帮我们解决什么问题?
- 找 CPU 性能瓶颈
- 看每帧里哪个模块耗时异常(颜色块明显突起)
- 快速定位卡顿来源:哪一帧卡了、卡在什么模块
- 找性能抖动
- 检查 GC 是否频繁(黄色峰值)
- 或者某帧脚本逻辑执行过重(蓝色占比高)
- 找优化依据
- 明确是脚本、渲染、物理还是 垂直同步(VSync)等模块引起的卡顿
- 帧率诊断
- 对比
16ms(60FPS)/33ms(30FPS)标尺,判断是否达标
- 对比
垂直同步为什么会影响帧率,如何设置
为何会影响
显示器通常以固定频率刷新画面(如 60Hz 表示每秒刷新 60 次,每帧约 16.67ms)。但显卡渲染速度不固定:有时快于显示器刷新,有时慢于。
垂直同步(VSync)会强制显卡“按显示器节奏交帧”:
- 等显示器准备好再提交新帧(等一次“垂直回扫”信号),避免屏幕撕裂
- 如果显卡渲染太快,它需要等一等
- 如果渲染太慢,可能会错过刷新窗口,导致延后一轮提交
影响帧率常见两种情况:
- 帧率略高于刷新率 → 强制等待
- 例如显卡能跑 90FPS,显示器 60Hz;开启 VSync 后,GPU 每
16.67ms才交一帧 → 体验上会被“卡”在 60FPS
- 例如显卡能跑 90FPS,显示器 60Hz;开启 VSync 后,GPU 每
- 帧率低于刷新率 → 被“降档”处理
- 例如当前只能 50FPS,VSync 要求必须整除刷新频率,于是可能被“降档”到 30FPS(60Hz ÷ 2)
这会造成明显卡顿或掉帧感
- 例如当前只能 50FPS,VSync 要求必须整除刷新频率,于是可能被“降档”到 30FPS(60Hz ÷ 2)
何时开关
- 开发调试时:通常先关闭 VSync,观察更真实的性能瓶颈
- 低端机运行卡顿时:关闭 VSync 有时能避免“锁档”带来的更强掉帧感
- 正式发包时:一般开启 VSync 防止撕裂(或交给玩家在设置中控制)
如何设置
- 代码控制
QualitySettings.vSyncCount = 0;
// 0:关闭垂直同步
// 1:每帧同步
// 2:隔一帧同步
- 编辑器中设置
垂直同步相关:Edit > Project Settings > Quality

Don't Sync(0):关闭 VSyncEvery V Blank(1):每次垂直同步(默认)Every Second V Blank(2):隔一帧同步(更低帧率)
5.2 知识点代码
Lesson05_Unity性能分析工具_CPUUsage.cs
public class Lesson05_Unity性能分析工具_CPUUsage
{
#region 知识点一 CPU Usage是什么
/*
* CPU Usage(CPU 使用率)
* - Unity Profiler 中最重要的性能分析模块之一
* - 用于展示每一帧 CPU 所花费的时间,并按类别细分不同系统的消耗情况,帮助诊断性能瓶颈
*
* 游戏开发中常见 CPU 开销来源:
* 1. 脚本逻辑(我们编写的 C# 代码逻辑)
* 2. 物理系统(Unity 内置物理引擎)
* 3. 动画计算(状态机、骨骼动画混合采样等)
* 4. 渲染准备(可见性/剔除/构建绘制命令/渲染命令提交等)
* 5. 资源管理和加载(AssetBundle/场景/纹理/网格/材质等元数据)
* 6. GC(垃圾回收)
* 7. UI 系统(布局计算、事件派发、渲染数据准备等)
* 8. 导航与寻路
* 9. 音频处理
* 10. 输入检测
* 11. 网络通讯
* 12. 屏幕后处理 C# 部分
* ……等等
*
* 一般项目出现卡顿、掉帧问题可以着重排查此处。
*/
#endregion
#region 知识点二 CPU Usage中个参数功能的含义和作用
/*
* CPU Usage 各参数的含义与作用:
* - 详见笔记正文(CPU Usage 分析窗口、模块详细信息面板、四种视图、字段含义等)
*/
#endregion
#region 知识点三 CPU Usage对于我们的意义
/*
* 1. 找 CPU 性能瓶颈:哪帧卡了、哪个模块卡了
* 2. 找性能抖动:GC 是否频繁、脚本是否突然变重
* 3. 找优化依据:脚本/渲染/物理/VSync 等哪个是主要原因
* 4. 帧率诊断:对比 16ms(60FPS)/33ms(30FPS)等标尺,判断是否达标
*/
#endregion
#region 知识点四 垂直同步为什么会影响帧率,如何设置
/*
* 为何影响:
* - 显示器刷新有固定节奏(例如 60Hz ≈ 16.67ms/帧),VSync 会让 GPU 按刷新节奏交帧
* - GPU 太快会等待,GPU 太慢会错过刷新窗口,可能出现“锁档/掉帧”
*
* 何时开关:
* - 开发调试通常先关,观察更真实的瓶颈
* - 低端机卡顿时关掉可能更顺(避免锁档)
* - 正式包常开防撕裂(或提供给玩家设置)
*
* 如何设置:
* - 代码:QualitySettings.vSyncCount = 0/1/2
* - 编辑器:Project Settings > Quality
*/
#endregion
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com