1.Mono托管堆(C#内存)
2.Unity总体内存情况
3.针对某个对象分析内存
4.特定分析部分逻辑
1.Mono托管堆(C#内存)
1).Profiler.GetMonoHeapSizeLong()
a.核心含义
托管堆的总分配容量(字节), 即Unity为托管内存分配的堆空间总大小
b.数值逻辑
代表托管堆的"总盘子", 是堆的整体容量
c.与GC的关系
仅在堆"扩容"时增长, GC不会使其减少(堆扩容后不自动缩容)
d.数值关系
始终 ≥ GetMonoUsedSizeLong() -> 堆总容量 ≥ 已用空间
2).Profiler.GetMonoUsedSizeLong() / Profiler.usedHeapSizeLong
a.核心含义
托管堆中实际被使用的内存大小(字节)
b.数值逻辑
代表堆中"已用的部分", 仅包含有引用的托管对象(如类实例、字符串、数组等)
c.与GC的关系
GC回收未引用对象后会显著下降, 对象创建时会上升
d.数值关系
始终 ≤ GetMonoHeapSizeLong()
2.Unity总体内存情况
1).Profiler.GetTotalReservedMemoryLong()
进程向操作系统申请的内存总量, 不管是否已经用上
2).Profiler.GetTotalAllocatedMemoryLong()
获取所有unity正在使用的内存总量(包括Mono, Native, 图形资源等)
3).Profiler.GetTotalUnusedReservedMemoryLong()
返回保留了但尚未分配出去的内存部分
"正在使用中的内存总量 + 保留了但尚未分配出去的内存部分 ≈ Unity从操作系统申请的内存"
3.针对某个对象分析内存
1).UnityEngine.Object是Unity引擎对象的核心基类:
a.每个UnityEngine.Object实例在C#层有一个包装对象, 同时在Unity原生(C++)层有对应的实例
b.Profiler.GetRuntimeMemorySizeLong的核心作用是"统计C#包装对象 + 原生层实例"的总内存占用(字节)
GameObject obj = new GameObject();
Profiler.GetRuntimeMemorySizeLong(obj);
c.普通c#对象无原生层实例, 仅存在于托管堆, 因此该API无法统计
2).UnityEngine.Object 子类

4.特定分析部分逻辑
开始一个自定义采样区段: 常用于标记性能热点段, 配合EndSample()使用; 会在Unity Profiler的CPU模块中显示为一条标
记, 建议仅在开发环境使用(#if UNITY_EDITOR)
Profiler.BeginSample("MrTangCode");
for (int i = 0; i < 99999; i++)
{
float x = Mathf.Sqrt(i);
}
Profiler.EndSample();