《天谕》手游的内存控制 -笔记

花了100块买了UWA上的这个课程,做个一个笔记

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。

  1. 格式ASTC8 x 8,部分精度要求高的6 x 6 或者 4 x 4

    Ios放弃iPhone5s/iPad mini3

    Android给低配机单独的包(ETC 8 bits)

  2. 【尺寸】控制贴图尺寸

  3. 【尺寸】针对不同贴图单独缩放尺寸

  4. 【Mipmaps】UI等贴图关闭Mipmaps,不然会多33%的内存

  5. 【Read/Write】关闭贴图的Read/Write Enabled,否则CPU和GPU都会有一份

  6. 【张数】去掉重复的贴图,合并通道减少贴图张数

《天谕》手游贴图规范:

Mesh内存优化Tips
  1. 控制网格定点和三角形数量
  2. Mesh Lod可以有效降低面数和内存
  3. 去掉不用的定点属性(uv, colors等等)
  4. 建议关闭网格的Read/Write

《天谕》手游的Mesh规范:

动画
  1. MMO帧率30基本够
  2. 严格控制动画时长
  3. Generic可以通过压缩浮点精度/去除scale曲线/keyframe reduction等方式进行压缩
  4. Humanoid动画比generic动画要小
  5. 压缩(Optimal 默认 2 2 2)
  6. 尽可能的复用动画资源(Retarget)
  7. Animator Controller会加载所有动画,需要优化
其他
  1. 中文字体裁剪(FontCreator + FontSubsetPack) 12M → 3M
  2. RenderTexture张数 尺寸 格式
  3. AssetBundle去掉TypeTree!可以减少30%-50%左右的内存,还可以略微提高加载解析速度
  4. 音频优化(通道/码率/streaming/按需加载)

三、脚本内存优化

  1. 控制高频的内存分配
  2. 控制大块的内存申请
  3. 控制容易导致gc alloc的函数调用
  4. 缓存和复用

《天谕》项目组的代码规范

代码C++化

why

  1. 提高运算性能
  2. 减少频繁调用导致的频繁GC

What

  1. XML文件解析
  2. 网络包处理
  3. 属性和战斗结算
  4. 数据表压缩

风险

  1. 无法热更
Shader内存优化

Shader这块没什么好说的,控制了一些变体之后,他们的总内存从130MB降到了41MB。

最后使用IPreprocessShaders将内存又降到了10Mb左右

四、总量控制、分级管理

由于《天谕》的资源太大,如果不做总量控制,直接加载进来的话,随时可能会撑爆内存。所以他们做了一套预算管理系统。控制着每个资源的创建,与自动降级。

对不同机型的配置,他们做了一个专门的设置界面,主要针对各种ios设备,设置各种高中低的开关

前期的资源,性能规范虽然很难做,但还是要去做。

这是他们的资源分析系统,可以看到有多个任务在执行。

最后的总结: