UPL3——Unity Profiler 脚本控制

本章代码关键字

1
2
3
4
5
6
7
8
9
10
11
Profiler.GetMonoUsedSizeLong()                    // 获取当前使用的Mono堆内存(单位:字节)
Profiler.GetMonoHeapSizeLong() // 获取Mono堆的总大小,用来判断Mono内存是否接近上限
Profiler.usedHeapSizeLong // 当前堆中使用的内存总量,包括所有托管内存
Profiler.GetTotalAllocatedMemoryLong() // 获取所有Unity正在使用的内存总量(包括 Mono、Native、图形资源等)
Profiler.GetTotalReservedMemoryLong() // 返回Unity从操作系统申请的内存总量,不管是否已经用上
Profiler.GetTotalUnusedReservedMemoryLong() // 返回Unity保留了但尚未分配出去的内存部分,即“空闲缓存池”
Profiler.GetRuntimeMemorySizeLong() // 获取某个对象占用的内存(估算值),包括纹理、网格等对象的实际内存占用
Profiler.BeginSample() // 开始一个自定义采样区段,常用于标记性能热点段
Profiler.EndSample() // 结束一个自定义采样区段
Profiler.enableBinaryLog // 控制是否将将Profiler数据写入文件
Profiler.logFile // 设置Profiler数据文件保存位置和文件名

Profiler 提供的重要API

Mono 托管堆(C# 层内存)

  • 获取当前使用的 Mono 堆内存(单位:字节),关注脚本(C#)对象占用的内存

    1
    Debug.Log($"Mono堆内存: {Profiler.GetMonoUsedSizeLong()}");

    image

  • 获取 Mono 堆的总大小,用来判断 Mono 内存是否接近上限

    1
    Debug.Log($"Mono堆内存总大小: {Profiler.GetTotalAllocatedMemoryLong()}");

    image

  • 当前堆中使用的内存总量,包括所有托管内存

    C# GC 堆当前被使用的内存(与 GetMonoUsedSizeLong() 类似,但更底层)。在某些平台下更准确。

    1
    Debug.Log($"堆内存使用大小: {Profiler.usedHeapSizeLong}");

    image

Unity 总体内存情况

正在使用中的内存总量 + 保留了但尚未分配出去的内存部分 ≈ Unity 从操作系统申请的内存总量:
GetTotalAllocatedMemoryLong()​ + GetTotalUnusedReservedMemoryLong()​ ≈ GetTotalReservedMemoryLong()

  • 获取所有 Unity 正在使用的内存总量(包括 Mono、Native、图形资源等)。常用于分析整体内存走势

    1
    Debug.Log($"Unity正在使用的内存总量: {Profiler.GetTotalAllocatedMemoryLong()}");

    image

  • 返回 Unity 从操作系统申请的内存总量,不管是否已经用上

    它包含:当前使用中的内存(已分配)、尚未使用但已预留的空间(为减少频繁申请)

    1
    Debug.Log($"Unity从操作系统申请的内存总量: {Profiler.GetTotalReservedMemoryLong()}");

    image

  • 返回 Unity 保留了但尚未分配出去的内存部分,即“空闲缓存池”

    1
    Debug.Log($"Unity保留了但尚未分配出去的内存部分: {Profiler.GetTotalUnusedReservedMemoryLong()}");

    image

针对某个对象分析内存

获取某个对象占用的内存(估算值),包括纹理、网格等对象的实际内存占用

1
2
GameObject obj = new();
Debug.Log($"对象占用的内存大小: {Profiler.GetRuntimeMemorySizeLong(obj)}");

image

特定分析部分逻辑

Profiler.BeginSample()​ 开始一个自定义采样区段,常用于标记性能热点段,配合 EndSample()​ 使用
会在 Unity Profiler 的 CPU 模块中显示为一条标记,建议仅在开发环境使用
可通过 #if UNITY_EDITOR 包裹避免构建时存在

1
2
3
4
5
6
7
8
9
10
11
12
13
void Update()
{
#if UNITY_EDITOR
Profiler.BeginSample("ProfilerTestCode");
// 做一些逻辑或渲染操作
for (int i = 0; i < 99999; i++)
{
float x = Mathf.Sqrt(i);
}
// 结束采样区段
Profiler.EndSample();
#endif
}

image

获取记录详细数据

可将 Profiler 数据写入文件,用于离线分析(比如上传给 QA 或分析工具)
是用于 在运行时手动采集 Unity Profiler 的原始性能数据(.raw 文件),这些数据可以导入 Unity Profiler 界面中进行离线分析。
我们一般可以在游戏中嵌入一个开启功能,采集一定时间的性能数据内容

1
2
3
4
5
6
7
8
private IEnumerator LogTest()
{
Profiler.logFile = Application.persistentDataPath + "/myProfileData.raw";
Profiler.enableBinaryLog = true; // 开始记录
yield return new WaitForSeconds(10f);
Profiler.enableBinaryLog = false; // 停止记录
//主动通过代码去上传采样数据到服务器
}

更多 Profiler API

更多 Profiler API,可见:Profiling.Profiler - Unity 脚本 API