22.Unity性能分析工具-Profiler窗口脚本控制
22.1 知识点
Profiler提供的重要API
使用以下 API 前需引用命名空间:using UnityEngine.Profiling;
Mono托管堆(C#层内存)
- Profiler.GetMonoUsedSizeLong() — 获取当前使用的 Mono 堆内存(单位:字节),用于关注脚本(C#)对象占用的内存。
- Profiler.GetMonoHeapSizeLong() — 获取 Mono 堆的总大小,用来判断 Mono 内存是否接近上限。正常情况应满足:
GetMonoUsedSizeLong() <= GetMonoHeapSizeLong()。 - Profiler.usedHeapSizeLong — 当前堆中使用的内存总量,包括所有托管内存;与 GetMonoUsedSizeLong 类似但更底层,在某些平台下更准确。
using UnityEngine.Profiling;
// 1. 当前使用的 Mono 堆内存(字节)
print("当前使用的Mono堆内存: " + Profiler.GetMonoUsedSizeLong());
// 2. Mono 堆总大小
print("Mono堆的总大小: " + Profiler.GetMonoHeapSizeLong());
// 3. 当前堆使用总量(托管内存,部分平台更准确)
print("当前堆中使用的内存总量: " + Profiler.usedHeapSizeLong);
Unity 总体内存情况
- Profiler.GetTotalAllocatedMemoryLong() — 获取所有 Unity 正在使用的内存总量(Mono、Native、图形资源等),常用于分析整体内存走势。
- Profiler.GetTotalReservedMemoryLong() — 返回 Unity 从操作系统申请的内存总量(已分配 + 已预留未用)。
- Profiler.GetTotalUnusedReservedMemoryLong() — 返回「空闲缓存池」,即保留了但尚未分配出去的部分。
三者关系:已使用 + 未使用但已预留 ≈ 从系统申请的总量。
using UnityEngine.Profiling;
long allocated = Profiler.GetTotalAllocatedMemoryLong(); // 正在使用的内存总量
long reserved = Profiler.GetTotalReservedMemoryLong(); // 从操作系统申请的总量
long unused = Profiler.GetTotalUnusedReservedMemoryLong(); // 保留但未分配的部分
// allocated + unused ≈ reserved
print($"已使用: {allocated}, 已预留: {reserved}, 空闲缓存: {unused}");
针对某个对象分析内存
- Profiler.GetRuntimeMemorySizeLong(object) — 获取某个 Unity 对象占用的内存(估算值),包括纹理、网格、GameObject 等。
using UnityEngine.Profiling;
GameObject obj = new GameObject("Test");
long size = Profiler.GetRuntimeMemorySizeLong(obj); // 单位:字节
print($"该对象占用内存约: {size} 字节");
特定分析部分逻辑
- Profiler.BeginSample / Profiler.EndSample — 开始/结束一个自定义采样区段,在 Profiler 的 CPU 模块中显示为一条标记;二者需成对使用。建议仅在开发环境使用,可用
#if UNITY_EDITOR包裹避免打进正式包。
using UnityEngine.Profiling;
Profiler.BeginSample("我的热点逻辑");
// 要分析的代码
for (int i = 0; i < 1000; i++) { /* ... */ }
Profiler.EndSample();
获取记录详细数据
- Profiler.logFile、Profiler.enableBinaryLog — 将 Profiler 数据写入 .raw 文件,用于离线分析(可导入 Unity Profiler 或上传给 QA)。一般在游戏中做「开始采集 / 停止采集」功能,采集一段时间后再上传或本地分析。
using UnityEngine.Profiling;
// 指定输出路径
Profiler.logFile = Application.persistentDataPath + "/myProfileData.raw";
Profiler.enableBinaryLog = true; // 开始记录
// 运行一段时间后……
// yield return new WaitForSeconds(10f);
Profiler.enableBinaryLog = false; // 停止记录
// 之后可上传 myProfileData.raw 或导入 Profiler 查看
更多Profiler API
更完整的接口说明见官方文档:
https://docs.unity3d.com/cn/2022.3/ScriptReference/Profiling.Profiler.html
22.2 知识点代码
Lesson22_Unity性能分析工具_Profiler窗口_脚本控制.cs
using UnityEngine;
using UnityEngine.Profiling;
public class Lesson22_Unity性能分析工具_Profiler窗口_脚本控制 : MonoBehaviour
{
void Start()
{
#region 知识点一 Profiler提供的重要API
/* 需要引用命名空间 using UnityEngine.Profiling; */
#region Mono托管堆(C#层内存)
/* 1. 获取当前使用的 Mono 堆内存(单位:字节);关注脚本(C#)对象占用的内存 */
print("当前使用的Mono堆内存:" + Profiler.GetMonoUsedSizeLong());
/* 2. 获取 Mono 堆的总大小;用来判断 Mono 内存是否接近上限 */
print("Mono堆的总大小:" + Profiler.GetMonoHeapSizeLong());
/* 正常来说 GetMonoUsedSizeLong() <= GetMonoHeapSizeLong() */
/* 3. 当前堆中使用的内存总量,包括所有托管内存;
* C# GC 堆当前被使用的内存(与 GetMonoUsedSizeLong 类似,但更底层),在某些平台下更准确。 */
print("当前堆中使用的内存总量;包括所有托管内存" + Profiler.usedHeapSizeLong);
#endregion
#region Unity 总体内存情况
/* 4. 获取所有 Unity 正在使用的内存总量(包括 Mono、Native、图形资源等);常用于分析整体内存走势 */
long totalMemory = Profiler.GetTotalAllocatedMemoryLong();
print("Unity 正在使用的内存总量:" + totalMemory);
/* 5. 返回 Unity 从操作系统申请的内存总量,不管是否已经用上;
* 包含:当前使用中的内存(已分配)、尚未使用但已预留的空间(为减少频繁申请) */
print("Unity 从操作系统申请的内存总量:" + Profiler.GetTotalReservedMemoryLong());
/* 6. 返回 Unity 保留了但尚未分配出去的内存部分,即“空闲缓存池” */
print("Unity 保留了但尚未分配出去的内存部分:" + Profiler.GetTotalUnusedReservedMemoryLong());
/* 正在使用中的内存总量 + 保留了但尚未分配出去的内存部分 ≈ Unity 从操作系统申请的内存总量
* GetTotalAllocatedMemoryLong() + GetTotalUnusedReservedMemoryLong() ≈ GetTotalReservedMemoryLong() */
#endregion
#region 针对某个对象分析内存
/* 7. 获取某个对象占用的内存(估算值);包括纹理、网格等对象的实际内存占用 */
GameObject obj = new GameObject();
Profiler.GetRuntimeMemorySizeLong(obj);
#endregion
#region 特定分析部分逻辑
/* 8. 开始一个自定义采样区段;常用于标记性能热点段,配合 EndSample() 使用。
* 会在 Unity Profiler 的 CPU 模块中显示为一条标记,建议仅在开发环境使用。
* 可通过 #if UNITY_EDITOR 包裹避免构建时存在。 */
Profiler.BeginSample("MrTaoCode");
/* 做一些逻辑或渲染操作 */
for (int i = 0; i < 99999; i++)
{
float x = Mathf.Sqrt(i);
}
/* 结束采样区段 */
Profiler.EndSample();
#endregion
#region 获取记录详细数据
/* 9. 可将 Profiler 数据写入文件,用于离线分析(比如上传给 QA 或分析工具)。
* 在运行时手动采集 Unity Profiler 的原始性能数据(.raw 文件),可导入 Profiler 界面中离线分析。
* 一般可在游戏中嵌入开启功能,采集一定时间的性能数据,再主动上传采样数据到服务器。 */
Profiler.logFile = Application.persistentDataPath + "/myProfileData.raw";
Profiler.enableBinaryLog = true; /* 开始记录 */
/* yield return new WaitForSeconds(10f); */
Profiler.enableBinaryLog = false; /* 停止记录 */
#endregion
#endregion
#region 知识点二 更多Profiler API
/* https://docs.unity3d.com/cn/2022.3/ScriptReference/Profiling.Profiler.html */
#endregion
}
void Update()
{
Profiler.BeginSample("MrTaoCode");
/* 做一些逻辑或渲染操作 */
for (int i = 0; i < 99999; i++)
{
float x = Mathf.Sqrt(i);
}
/* 结束采样区段 */
Profiler.EndSample();
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com