排查分析
在运行状态下抓取内存快照,在快照中,排查[对象和分配]。在列表中按类型排序,可以看到有一张较大的RenderTexture,怀疑是项目中的某张尺寸为2560x1320的贴图。
对于
2560x1320
的 RenderTexture,如果每像素占用4
字节(例如RGBA32
格式),则大小为:2560 × 1320 × 4 = 13,516,800 字节 ≈ 12.9 MB
应该就是它。
最初开发时,是直接在Resources目录下创建的,由场景中的预制体持有其引用。
这样,它就会在运行时被加载,即便在没有使用,也会占用内存。
优化方案
动态创建与绑定
为了减少内存占用,我们可以等到要使用RenderTexture的时候,再动态创建纹理,并绑定到相机和 UI 组件上。
fullScreenTexture = new RenderTexture(2560, 1320, 0);
camera.targetTexture = fullScreenTexture;
fullScreenRawImage.texture = fullScreenTexture;
释放内存占用
在使用完毕后,清除所有引用,并销毁RenderTexture。
camera.targetTexture = null;
fullScreenRawImage.texture = null;
Destroy(fullScreenTexture);
fullScreenTexture = null;
强制回收内存
在测试中,我们发现调用Destroy(fullScreenTexture)后,内存并未立即释放。这是可能是因为 GC只是将这块内存标记为“可回收”,而不会立即回收。如果想要立即回收,可以调用:
Resources.UnloadUnusedAssets();
在回收之后,可以在MemoryProfiler中看到它的内存占用被释放。