内存管理
Q1:有没有办法可以减少游戏中Mono内存占用的大小?我现在读完游戏表以后就占用了60MB,我看其他游戏读完配置表也才10MB左右,这个是怎么做到的呀?
如果刚进入游戏后,Mono堆内存就达到了60MB,那么你的游戏项目极有可能在一开始加载了一个非常大的配置表。对此,我们建议出现该问题的研发团队对配置文件的初始加载进行详细检测,查看是否可以精简配置文件信息。如果不行,则尝试将配置文件拆散,按需加载,从而降低Mono内存上升过快问题发生的概率。
内存管理
Q2:在我的UWA性能检测报告中,纹理才占50MB,但为什么Unity内存会有300MB之多,请问这部分是怎么计算的?内存大小难道不是由资源大小决定的吗?
对于绝大多数平台而言,Reserved Total内存 = Reserved Unity内存 + GFX内存 + FMOD内存 + Mono内存。Reserved Unity为Unity引擎自身各个模块内部的内存分配,包括各个Manager的内存占用、序列化信息的内存占用、WebStream的内存占用和部分资源的内存占用等等,所以纹理资源仅是Unity引擎使用内存的一部分。除纹理资源外,研发团队还需要注意Mesh资源、AnimationClip、RenderTexture、Font资源等等,同时还需要关注AssetBundle文件在内存中的驻留情况(可在UWA报告中的“资源管理->具体AB使用情况”页面中查看),因为它可能会导致SerializedFile和Webstream内存(Unity5.3版本后不再有WebStream)的内存占用过高。
内存管理
Q3:我最近用Deep Profiler发现项目里有一个直接调用Color != Color的接口耗时很高,而且百分比也很高(不管是Self还是Total)。但是如果用Profiler.BeginSample显示时,其耗时又很低,百分比也很低几乎等于0。这样的情况下是Deep Profiler出问题了吗?
针对上图具体例子来看,Deep Profiler中RoleRender_ChangeColor.get_running的CPU开销虽然较高,但其参考意义不大。因为不开Deep Profiler模式,此处开销是不会这么高的。这是因为,图中的开销实际上是操作了200次循环且获取时间戳的开销,也就是说,当循环或者操作大量次数时,Deep Profiler模式中本身统计耗时操作的时间占比很大,所以此处反馈的时间其实并不是研发团队想看到的真正代码耗时。这也是为何很多团队反馈Deep Profiler统计不算准确的原因。
内存管理
Q4:Unity中修改了Material的一个属性后,该Object就会单独实例化出一个Material,所以它就不能被动态Batching了,是这样吗?
是的,所以我们在Material使用详情中对内存中驻留的Material进行了详细的检测和分析,如下图所示。
图中后缀为(Instance)的材质均为修改材质属性而生成的临时材质,对于这种情况,我们建议研发团队应严格将Instance材质数量控制在尽可能小(<10)的范围内,而对于过高数量的Instance材质,建议研发团队考虑是否可以通过动态更换Material的方式来代替修改材质属性的方式,从而来减少不必要的Instance材质,进而提升物体动态合批的几率。
内存管理
Q5:网格模型FBX文件在不开启Read/Write选项时, 如果通过StaticBatchingUtility的CombineMesh来合批的话,内存会增加么?
通过StaticBatchingUtility的CombineMesh来动态地拼合网格是会增加内存的,主要体现在内存中CombinedMesh的增加以及一定量堆内存的增加。但是,该API使用的前提必须是网格Fbx模型开启Read/Write,如果不开启,则无法读到网格数据,进而不能完成网格的拼合操作。