前言
一般Unity项目的内存主要分为如下方面:
资源内存
mono内存
dll内存
lua内存
资源内存的分析与优化
合理的资源标准
资源标准因项目而异
1.如何定制合理的资源标准
1)根据项目定位受众的目标设备的性能峰值(比如内存不要超过2G),自上而下的进行规划。
2)若是目标机型的性能越有限,那么项目的资源划分应该更有侧重点,比如项目主要时卖皮肤,又想同屏很多玩家,那么可以在不太影响体验的前提下,挪出其他资源的内存到角色的外观上。
mono内存的分析与优化
某个时刻内存占用分析
内存占比合理性
前后时刻内存对比分析
内存分配合理性
方法一:利用memory profiler的compare snapshots功能
1)分别对测试过程的不同时刻进行采样。
2)Single Snapshot中选中的第一个项作为A,切入compare snapshots后选中选择的项作为B,选择完后就会自动生成对比结果。也可以通过调换按钮来让AB对调。
3)可按顺序对diff、type进行group操作,然后在对size排序,可以更看到新增和删除的有多少内存,分别有哪些,大头是什么。
4)
泄露分析
如何才算泄漏
1)一段时间,持续分配,不会消减的对象。
2)
组件实例泄露
组件实例泄露是指:gameObject已调用的Destory,但是memory profiler能捕抓到无名的组件实例对象。(2021版本的memory profiler会右侧的status标记出可能是leaked对象。)
1)可以通过泄露对象的属性辅助定位从属于哪个模块,把分析的范围缩小到该模块的代码。(比如下面的ui.text泄露,从text字段可知是任务相关模块)
碎片分析
fragmented内存是如何产生的?
1)A模块申请了非常大的a内存,使用完后释放,B模块申请非常小的b内存,位置在之前的a内存内,此时A模块再想申请跟a内存一样大的内存时,由于b内存穿插在之前的a内存内,系统只能另外找一块新的内存分配给A模块,因此a内存内很多空闲空间就未被利用起来了。
如何知道一块fragmented内存是来源?
1)若是正在使用中的地址,在Objects and Allocations中显示Address并对它进行match定位,它的详情。
下面的案例搜到是unity sbp持有的BundleDetails中的ab数据。
lua内存的分析与优化
lua闭包引用了C# 组件实例
table在GetText的时候,将text的实例push包装成userdata缓存到ObjectTranslator的对象池中。
dll内存占用优化
可以通过在memory profiler里Select Table View-> Raw Data -> Managed Type来赋值筛选使用的类。