Unity3D实例:内存使用的分析实践

发表于2016-08-12
评论0 3.1k浏览

这是一次内存使用的分析实践,开发环境是 Unity 5.3.4p5 + uGUI

======

经过真机WeTestadb shellUnity MemoryProfiler、代码走读这几种手段观察,理解客户端的内存使用情况。

 

一、真机WeTest测试,并上传测试数据。

WeTest是一个测试插件,独立于游戏客户端本身。

 

操作①:启动游戏,打开根性忍传系统,打一局,胜利后回到主界面。

登录前后200M上下,战斗后超过360M,回到主界面也一直保持在360M

 

操作②:退出重新进入游戏,并打开全部系统UI界面(不打开副本地图,也不进入战斗)。

登录前后200M上下,逐个系统UI界面打开,内存从220M缓慢增加,并最后基本保持在270M上下。

 

操作③:进入副本地图,并打第四章最后一关。

战斗开始后内存增长到了420M,回到主界面也一直保持在420M

 

操作④:继续玩一局精英副本、一局普通副本、一次排位赛、一次根性忍传、跑一次组织护送,再次逐个系统界面点开一次(除了副本地图)。

内存增长到430M440M

 

从一次简单操作(操作①),以及一次完整操作(操作②③④),大致可看到:

除副本和战斗以外全部系统大概需要270M内存,而副本和战斗大概需要额外160M内存

 

二、通过adbshell命令查看内存情况。

adb shell dumpsys meminfocom.tencent.narutotbs

游戏登录后:

 

一轮完整操作(上述操作②③④)后:

看到的Pss数据基本跟WeTest一致(WeTest内存值应是通过Linux命令获得的Pss数据)。

注意其中EGLmtrackGL mtrack,以及诡异的Unknown部分的大小,它们之和基本上就是Pss的大小。

 

三、UnityMemoryProfiler观察

Unity5.3之后提供了一个更直观的内存工具:MemoryProfiler

游戏登录前的内存各资源类型分布:

其中Texture2D还不是大头,大约占1/5

一轮完整操作(上述操作②③④)后的内存各资源类型分布:

其中Texture2D已然是大头。

两者对比看,登录前Texture2D只有13.3MB,而之后增加到了1.5GB

由于编辑器的资源格式是ARGB 32bit,而打包成APK/IPA则采用压缩ETC/PVRTC 4bit,而且Unity MemoryProfiler会算双份(比如1024*1024*32bit显示8MB,实际应是4MB),

所以这里Texture2D实际占用大约是1.5GB/8/2=100MB

Unity MemoryProfiler显示了每个图片资源被引用的Root节点,整理发现大头是以下这四个:

CommonResCache

缓存VIew界面等Asset资源

BattleResCache   

缓存战斗内的忍者帧动画等资源

DungeonResCache

缓存副本地图的背景图片等资源

IconResCache    

缓存忍者半身像、忍者头像Icon、技能Icon、道具Icon等资源

 

四、代码走查Cache使用

经过一轮完整操作(上述操作②③④)后,断点发现:

其中IconResCache缓存的资源key数量相对较多,这是因为它是按文件名+Sprite综合索引。

这几个XxxResCache管理各自分类的资源Cache的加载与更新、淘汰与卸载。

 

资源淘汰则根据不同机型有不同阈值与淘汰策略

比如对于低端机,XxxResCache缓存数量更少,且退出战斗时清空BattleResCache

 

IconResCache的淘汰策略相对特殊,仅对忍者半身像作淘汰,不对忍者头像Icon、技能Icon和道具Icon等资源作淘汰。这是因为忍者半身像是独立的图片资源,可以卸载任意一个或几个。

 

而其他Icon是整合在一张图片的,不能仅卸载其中某几个Icon,要想卸载就得卸载整张图片,但是下次使用又得重新加载整张图片,会引起额外的卡顿。此处考虑内存与CPU的平衡点

 

不过,对于其中内容较“空”的资源,可考虑裁剪成多张尺寸小一号的资源,比如下面的道具Icon、忍者Icon、技能Icon

但是资源裁切又会引入额外Drawcall,以及增加资源维护成本(增加字段、额外配表)。此处考虑内存与GPU、资源维护的平衡点

 

为了实现重力感应的效果,主界面把背景图片裁成远近不同的几个子图片。从策划角度可以考虑下如何优化内存。普通副本大章选择界面也是类似。此处考虑内存与游戏体验的平衡点

 

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引