UPL2-5——Memory 模块

Memory 模块

Memory(内存)模块是 Unity 中用于监视 内存使用情况 的关键工具
它能帮助你识别哪些资源在占用大量内存,是否存在内存泄漏或垃圾回收频繁等问题

游戏开发中会造成内存开销的主要有:

  1. 纹理贴图
  2. 网格
  3. 音频/视频
  4. 动画
  5. 材质球和 Shader
  6. C# 托管堆内存
  7. 场景中的各 GameObject 以及各组件

等等

在游戏中如果出现以下问题时,可以着重观察这里的内容:

  1. 游戏卡顿、掉帧

    表现:游戏突然变慢、不定期小卡顿、操作延迟等
    可能原因:内存不足导致系统频繁进行 垃圾回收(GC),降低游戏帧率

  2. 闪退、崩溃

    表现:玩着玩着突然黑屏退出、特定场景(如加载大地图)崩溃
    可能原因:设备分配不出更多内存,系统强制杀掉进程

  3. 加载时间变长

    表现:加载界面等待时间变长,场景切换明显卡顿
    可能原因:加载资源时需要更多内存,系统调度与 GC 频繁运行。

  4. 发热严重、掉电快

    表现:手机发烫严重、电池消耗快
    可能原因:设备内存使用达到极限,系统/游戏频繁调度内存资源,CPU、GPU 都高负载运转

  5. 低端设备无法运行

    表现:打开即闪退、进主界面就崩溃
    可能原因:老旧设备的可用内存更少,超出后甚至无法加载首屏

等等

Memory 中各参数功能的含义和作用

注:如果你的工程内安装了 Memory Profiler Package 这个包,那么下方 Simple 显示的内容会有所不同
这里演示的是未安装 Memory Profiler Package 的情况,关于 Memory Profiler Package 会在后续阐述 ——> UPL2-6——Memory Profiler Package

image

  • Memory(内存)分析窗口 在这里显示有关内存的相关统计信息

    image

    • Total Used Memory: 已使用的内存总量(包括纹理、网格、对象、脚本等所有内存) 是最直观的内存压力指标
    • Texture Memory: 贴图纹理使用的内存总量(包括 Mipmap) 通常是内存占用的最大部分
    • Mesh Memory: 网格使用的内存总量(顶点、索引缓冲等) 和场景中物体数量密切相关
    • Material Count: 材质数量 材质越多越难合批、内存占用也高
    • Object Count: 内存中的 UnityEngine.Object实例总数包括贴图、网格、脚本、GameObject 等) 过高可能意味着资源未卸载干净
    • GC Used Memory: GC(托管堆)使用的内存(堆已分配但仍被使用)
    • GC Allocated In Frame: 该帧分配的托管堆内存

    使用建议:

    1. 排查 GC 问题时,可以重点观察 GC Allocated In Frame 是否频繁跳动
    2. Texture Memory 如果过高,要检查是否贴图分辨率太大、未压缩、重复加载
    3. Mesh Memory 可反映模型复杂度,是否存在不合理的高面数网格
    4. Object Count 超高时,注意是否存在对象未正确卸载,是否存在未销毁的临时 Gameobject

    等等

  • Simple 视图 展示的是 Unity 运行时的内存占用概况,用于快速判断内存使用情况

    它可以帮助我们:

    1. 看懂 Unity 总共用了多少内存
    2. 哪些资源类型是主要的内存消耗者
    3. GC 是否活跃(有没有频繁分配)
    4. 是否存在异常占用(比如 Profiler 本身占用过大)

    等等

    注意: 对于空场景都有 Textures、Meshs 等对象的分配和内存占用
    这是因为 Unity 即使是空场景,也会默认加载一些内建资源,
    比如内置字体、编辑器用到的各种图标、GUI 样式、Gizmos 相关资源、Profiler 自己的资源,这些内容其实不属于你的游戏资源

    image

    • Normalized(规范化): 将所有帧的内存占用按相同的最大值进行统一缩放显示

      这样你可以更直观地比较多帧之间各类内存(比如贴图、堆内存、Profiler、Audio 等)的占用比例变化
      未勾选时,各帧是按自己的比例显示的,视觉对比就不太直观了
      勾选后可以帮助我们分析内存是否稳定,对比 不同类型资源的内存占比变化,从而查找 内存激增、泄漏等问题

    • Total Committed Memory(总提交内存): 表示 Unity 总共已分配的内存(虚拟内存),包括系统预留 + 实际使用

      image

      即 Unity 请求了多少内存资源,无论是否真正用了

      • Tracked Memory(跟踪的内存): Unity 能追踪的内存(即 Memory Profiler 能看见的部分)包括 托管堆内存、图形资源、音视频等等

        • In use:实际使用量
        • Reserved:为未来分配预留的空间
      • Untracked Memory(未跟踪的内存): Unity 已使用但未跟踪的内存总量,比如本机插件、Mono 或 IL2CPP 的元数据,DLL等

        如果你用 C++ 插件或 NativeArray 没正确释放,会在这体现出问题

    • Total Memory Breakdown: 总内存细分,显示和总提交内存相同的总量,会显示具体是为Unity的哪些子系统分配了多少内存

      image

      • Managed Heap: 托管堆内存使用情况;正在使用/预留内存 此内存会被垃圾回收,即由 C# 脚本分配的对象内存

        • In use:实际使用量
        • Reserved:为未来分配预留的空间
      • Graphics & Graphics Driver:图形/图形驱动程序分配的内存。 驱动程序对纹理、渲染目标、着色器、网格数据等分配的内存

      • Audio:音效系统预估内存使用量

      • Video:视频系统预估内存使用量

      • Other:其它系统内存使用情况 未归类但可追踪的内存,如 Unity 编辑器自身的一些缓存结构

      • Profiler:Unity Profiler 本身占用的内存(采样数据、快照等)

      • Untracked Memory:Memory Profiler 无法追踪的内存使用量

    • Object Stats(对象统计信息):资源类对象的数量与内存分布概况

      image

      • Textures: 已加载的纹理总数及其使用的内存
      • Meshes: 已加载的网格总数及其使用的内存
      • Materials: 已加载的材质总数及其使用的内存
      • Animation Clips: 已加载的动画剪辑总数及其使用的内存
      • Assets: 已加载的资源总数
      • Game Objects: 场景中的游戏对象实例的总数
      • Scene Objects: Scene 中所有对象总数,包含 Gameobject、组件以及场景中不属于资源的所有内容
      • GC allocated in frame: 该帧分配的托管堆内存数量和总大小

Memory 对于我们的意义

Memory 可以帮助我们

  1. 精准定位内存占用来源

    可以详细查看哪些内容(脚本、贴图、网格、音频等等)占用内存多,判断哪些部分可以进行优化压缩,重复利用

  2. 分析是否存在内存泄漏

    可以通过对比不同帧内存使用情况,发现是否存在不使用但未被释放的内存

  3. 验证资源卸载是否生效

    可以通过对比不同帧内存使用情况,验证是否如预期释放了资源

  4. 检查GC压力来源

    排查哪些脚本对象存在大量分配

  5. 决定内存优化策略

    可以根据发现的问题,制定优化策略

等等