首页 热点资讯 义务教育 高等教育 出国留学 考研考公
您的当前位置:首页正文

02. 内存分析

2024-12-20 来源:化拓教育网
  1. 内存部分
  2. 理解托管堆 【推荐阅读】
    5.1
    5.2
  3. 字符串和文本
  4. 资源目录
  5. 通用的优化方案
  6. 一些特殊的优化方案

内存消耗是关键的性能指标,尤其对于在内存资源非常有限的设备上,如移动设备。

剖析内存消耗

注意,这个工具在Unity5.3之后的版本都可以使用,如果应用是用IL2CPP打包的,它可以提取原生代码和托管代码的内存消耗信息。

使用这个工具,需要使用IL2CPP工具进行打包并且发布到合适的设备上,然后连接上编辑器中的CPU剖析工具,打开内存剖析界面(Window > MemoryProfilerWindow)选择Take Snapshot。

设备上收集数据,并将这些数据发送给Unity编辑器,应用会暂停一段时间。然后Unity编辑器开始分析数据,这也需要比较久的时间。对于内存比较敏感的应用,这个过程可能需要10-30分钟完成。

在解析数据和加载的过程中,建议各位耐心等待。

image.png

上面的截图来自于iOS设备上运行的标准Asset场景,显示了四分之三多的内存给了四个非常大的飞行器的机身纹理贴图。

这个可视化的工具也可以被放大。点击每个方块可以获得更多的相关信息。

定位重复的纹理

最常见的内存问题是在内存中的资源重复。纹理是最占内存开销的资源类型,纹理重复是Unity项目中最常见的问题。

如果两个对象是相同大小,相同类型,那么很有可能这两个对象是从同一个Asset加载进来的。在新的内存剖析器中,可以通过Name和InstanceID观察查看资源。

Name是加载进来的Asset文件的名称,通常不带路径名和后缀。InstanceID是Unity采用的内部识别编号,在Unity运行的过程中,这个编号是独一无二的。

image.png

这张图示范了资源重复的一个例子。图形的左边和右边是从Unity5.4的内存剖析器中的某个细节面板。两张图的Asset实际上是内存中两个分开加载的纹理资源,名字和大小相同。可以在Assets目录下搜索资源名字,确认是否只有一个资源较这个名字,从而确定是不是资源重复加载。

内存中每个独立的UnityEngine.Object都有独特的instance ID,当Object被创建的时候指定。这两个纹理有不同的Instance IDs,所以它们代表了两份不同的纹理数据。

因为Asset的大小和名称相同,而InstanceID不同,所以可以确定一个纹理被加载了两次。虽然有可能会出现两个同名的资源文件,所以还是按照文件大小来判定。
AssetBundle和Asset重复
纹理资源和Asset重复的最大原因是AssetBundle的不合理使用。可以参见AssetBundle相关的知道。关键章节是管理已经加载的Asset。

检查图片缓冲区,图片效果和RenderTexture内存使用

同样也可以在剖析器中看到为图片效果和RenderTexture提供渲染缓冲区占用的内存大小。

image.png

上面的截图展示了使用了Unity电影图片效果的一个场景的内存剖析器的情况。这个图片效果分配了临时渲染缓冲区,而且Bloom效果分配了多个缓冲区。因为iOS设备的高分辨率,这些临时缓冲区占用了非常多的内存,比项目中剩下的占用的总数还多。

考虑到iPad Air2的分辨率是2048x1536,比大部分终端设备和PC的1080p的分辨率高出了很多。全屏的临时渲染缓冲区差不多消耗24MB~36MB,取决于缓冲区的格式。降低渲染缓冲区的像素大小可以节省75%的内存消耗,同时也不会对最终的效果造成很大的影响。

如果觉得文章对您有用,请点个赞呗!☺☺☺

显示全文