当前位置: 首页 > 文档资料 > UWA 帮助文档 >

内存占用

优质
小牛编辑
133浏览
2023-12-01

【内存占用】页面主要展示项目运行过程中内存的使用情况,主要包括以下几个部分:

数据汇总

该项主要展示项目运行过程中的 “总内存峰值”、“堆内存峰值”、“GFX内存峰值” 和 “泄露风险”。其中,总内存为Unity引擎所统计的真实物理内存分配,并不包含系统缓存和第三方库的自身分配内存; 堆内存所指的是 Mono 管理和分配的托管堆内存; GFX内存为用于渲染的资源所占用的内存,主要包括纹理资源、网格资源、Shader资源等; 泄露风险为我们通过以下图表中的内存走势而判断出的项目泄露风险程度。其判断依据主要为检测总内存的分配、各资源的内存占用是否存在逐步增高的趋势。

总内存和使用内存

该项主要展示项目运行过程中内存的使用情况。

Reserved TotalUsed Total 为Unity引擎在内存方面的总体分配量和总体使用量。 一般来说,引擎在分配内存时并不是向操作系统 “即拿即用”,而是首先获取一定量的连续内存,然后供自己内部使用,待空余内存不够时,引擎才会向系统再次申请一定量的连续内存进行使用。所以,从图表中可以看到,Reserved Total 的内存占用量略大于 Used Total, 且两者走势基本一致。

注意:对于绝大多数平台而言,Reserved Total内存 = Reserved Unity内存 + GFX内存 + FMOD内存 + Mono内存

Reserved UnityUsed Unity 为Unity引擎自身各个模块内部的内存分配,包括各个Manager的内存占用、序列化信息的内存占用、WebStream的内存占用和部分资源的内存占用等等。

通过针对大量项目的深度分析,我们发现导致 Reserved Unity 内存分配较大的原因主要有以下几种:

  • WebStream内存占用:WebStream为项目通过特定API(new WWW、CreateFromMemory等)加载AssetBundle文件所开辟的较大块内存。主要用于存放AssetBundle的原始数据和解压后数据。
  • 序列化信息内存占用:Unity引擎的序列化信息种类繁多,其中最为常见且内存占用较大的为 SerializedFile。该序列化信息的内存分配主要为项目通过特定API(WWW.LoadFromCacheOrDownload、CreateFromFile等)加载AssetBundle文件所致。
  • 资源内存占用:主要包括Mesh、AnimationClip、RenderTexture等资源。在默认情况下,当FBX模型导入时,其 “Read/Write Enable” 选项是默认开启的,即其Mesh网格数据会在 Reserved Unity 中保留一份,便于项目在运行时对Mesh数据进行实时的编辑和修改。同时,如果研发团队同样开启了纹理资源的 “Read/Write Enable” 选项(默认情况下为关闭),则纹理资源同样会在 Reserved Unity 中保留一份,进而造成其更大的内存占用。

GFX内存 为底层显卡驱动所反馈的内存分配量,该内存分配由底层显卡驱动所控制。一般来说,该部分内存占用主要由渲染相关的资源量所决定,包括纹理资源、Mesh资源、Shader资源以及解析这些资源的相关库所分配的内存等。

托管堆内存

托管堆内存 表示项目运行时代码分配的托管堆内存分配量。对于使用Mono进行代码编译的项目,其托管堆内存主要由Mono分配和管理;对于使用IL2CPP进行代码编译的项目,其托管堆内存主要由Unity自身分配和管理。目前,除iOS平台外,其他平台的绝大多数项目还在使用Mono来进行代码编译。

对于Mono堆内存来说,由于Mono自身的限制,其堆内存分配是 “只升不降” 的,即内存一旦分配给Mono,不论以后该内存是否继续被使用,都不会再归还给系统。因此,建议您对于代码的堆内存分配进行严格的控制,避免不必要的Mono堆内存分配。对此,我们在【代码效率——堆内存分配】页面中针对代码的堆内存分配进行了详细的统计,方便您对代码进行有的放矢地检测和优化。