《天谕》手游的内存控制 -笔记
Profiler工具
推荐使用XCode分析内存,更准确
一、内存指标的类型:
VSS:Virtual Set Size,虚拟耗用内存。它是一个进程能访问的所有内存空间地址的大小。这个大小包含了 一些没有驻留在RAM中的内存,就像mallocs已经被分配,但还没有写入。VSS很少用来测量程序的实际使 用内存。
RSS:Resident Set Size,实际使用物理内存。RSS是一个进程在RAM中实际持有的内存大小。RSS可能会 产生误导,因为它包含了所有该进程使用的共享库所占用的内存,一个被加载到内存中的共享库可能有很 多进程会使用它。RSS不是单个进程使用内存量的精确表示。
PSS:Proportional Set Size,实际使用的物理内存,它与RSS不同,它会按比例分配共享库所占用的内存。 例如,如果有三个进程共享一个占30页内存控件的共享库,每个进程在计算PSS的时候,只会计算10页。 PSS是一个非常有用的数值,如果系统中所有的进程的PSS相加,所得和即为系统占用内存的总和。当一个 进程被杀死后,它所占用的共享库内存将会被其他仍然使用该共享库的进程所分担。在这种方式下,PSS 也会带来误导,因为当一个进程被杀后,PSS并不代表系统回收的内存大小。
USS:Unique Set Size,进程独自占用的物理内存。这部分内存完全是该进程独享的。USS是一个非常有用 的数值,因为它表明了运行一个特定进程所需的真正内存成本。当一个进程被杀死,USS就是所有系统回 收的内存。USS是用来检查进程中是否有内存泄露的最好选择。
简单来说,主要我们检测PSS,USS。
USS = 进程独占的内存
RSS = USS + 共享内存
PSS = USS + 共享内存/共享这段内存的进程数量
如何获取PSS、USS
在unity中:
Debug.MemoryInfo localMemoryInfo = new Debug.MemoryInfo();
Debug.getMemoryInfo(localMemoryInfo);
localMemoryInfo.getTotalPss();
localMemoryInfo.getTotalPrivateDirty();//USS
使用adb:
adb shell dumpsys meminfo 进程名
(结果里privte dirty就是USS)
二、资源内存优化
贴图优化
主要还是讲的那些老生常谈的Tips。
-
格式ASTC8 x 8,部分精度要求高的6 x 6 或者 4 x 4
Ios放弃iPhone5s/iPad mini3
Android给低配机单独的包(ETC 8 bits)
-
【尺寸】控制贴图尺寸
-
【尺寸】针对不同贴图单独缩放尺寸
-
【Mipmaps】UI等贴图关闭Mipmaps,不然会多33%的内存
-
【Read/Write】关闭贴图的Read/Write Enabled,否则CPU和GPU都会有一份
-
【张数】去掉重复的贴图,合并通道减少贴图张数
《天谕》手游贴图规范:
Mesh内存优化Tips
- 控制网格定点和三角形数量
- Mesh Lod可以有效降低面数和内存
- 去掉不用的定点属性(uv, colors等等)
- 建议关闭网格的Read/Write
《天谕》手游的Mesh规范:
动画
- MMO帧率30基本够
- 严格控制动画时长
- Generic可以通过压缩浮点精度/去除scale曲线/keyframe reduction等方式进行压缩
- Humanoid动画比generic动画要小
- 压缩(Optimal 默认 2 2 2)
- 尽可能的复用动画资源(Retarget)
- Animator Controller会加载所有动画,需要优化
其他
- 中文字体裁剪(FontCreator + FontSubsetPack) 12M → 3M
- RenderTexture张数 尺寸 格式
- AssetBundle去掉TypeTree!可以减少30%-50%左右的内存,还可以略微提高加载解析速度
- 音频优化(通道/码率/streaming/按需加载)
三、脚本内存优化
- 控制高频的内存分配
- 控制大块的内存申请
- 控制容易导致gc alloc的函数调用
- 缓存和复用
《天谕》项目组的代码规范
代码C++化
why
- 提高运算性能
- 减少频繁调用导致的频繁GC
What
- XML文件解析
- 网络包处理
- 属性和战斗结算
- 数据表压缩
风险
- 无法热更
Shader内存优化
Shader这块没什么好说的,控制了一些变体之后,他们的总内存从130MB降到了41MB。
最后使用IPreprocessShaders将内存又降到了10Mb左右
四、总量控制、分级管理
由于《天谕》的资源太大,如果不做总量控制,直接加载进来的话,随时可能会撑爆内存。所以他们做了一套预算管理系统。控制着每个资源的创建,与自动降级。
对不同机型的配置,他们做了一个专门的设置界面,主要针对各种ios设备,设置各种高中低的开关
前期的资源,性能规范虽然很难做,但还是要去做。
这是他们的资源分析系统,可以看到有多个任务在执行。
最后的总结: