文章目录
项目背景
场景
- 1024*1024
- 同屏200W面
- 贴图1024
- 自由视角
配置表
- 1000+张配置表
- C++内存加载350MB
角色
- 同屏20人
- 45个职业变种
- 数万件时装
- 模型面数3-5W面
业务系统
- 3000+个界面
- 200W+行非生成代码
资源
- 10W+个AB
Unity版本
- 2019
内存分布
- Native Heap
- Code
- Graphic 图形内存
- Unknown
Native Heap
Native Heap用来存放 C++层(引擎层) 的各种对象和资源数据。
- Unity Engine 内部结构体、组件对象
- 资源(Texture、Mesh、AudioClip 等)的 CPU 端数据
- NativeContainer(如 NativeArray、NativeList 等)
- Job System / Burst 编译代码用到的临时缓冲区
- 底层系统调用(如物理系统、导航系统、动画系统)
Unknown
- 华佗HybridCLR热更新的元数据
定位工具
Native内存
环境配置
- Android Studio
- Profile
- Record Native Allocation
Code内存
环境配置
- Android Studio
- adb shell
- run-as com.Unity.ClassicSponza cat /proc/11810/maps | grep libil2cpp.so
Lua内存
- 递归遍历
关键指标
- Native内存: 200MB
- C++配置表: 30-40MB
- Graphic: 100MB
- Code: 100MB
- Mono: 100MB
- UnityNative: 200MB
- 总计750MB
常见优化手段
纹理贴图
- 图集
- ASTC压缩
- 关闭mipmap
- 九宫格
- 对称
- 单行渐变
- 单通道贴图
- 关闭ReadWrite
- 合理分辨率设置
- 超采样压缩
- streamingmipmap
模型
- LOD
- 优先级显示
- 剔除余通道
- 关闭ReadWrite
- 名字版替代
场景
- 公告板
- LOD
- 流式加载
- 分层显示
- 光照探针优化光照
特效
- 贴图256
- 总数限制
- 粒子最大数量限制
- LOD加载
- 去重
- 模型最大顶点数限制
动画
- 压缩格式
- 骨骼剔除
- 属性剔除
- 曲线压缩
音频
- 压缩格式设置
- 单通道
- streaming
- lazy加载
字体
- 静态图集
- 动态图集
- ttf剔除
Shader
- 变体剔除
优化案例
Mono内存
- 去除字符串
- gc替代缓存
- 数据转移C++
- 精简数据结构
- 延迟加载
- 精准卸载
代码元数据优化(Metadata)
IL2CPP在使用到某个类型时,会初始化这个类型完整的元数据,包括它的所有函数、接口、事件、属性、虚函数表等,并且一旦加载后就不会再释放。所以一个MMO游戏中,充分运行后,代码元数据占用的内存会非常高。
- 排查泛型Template用的是否较多
- 排查自动化生产的代码是否较多
- 排查Lua生产的Wrapper代码是否较多
- 删除无用插件、代码
- 排查IL2CPP是否进行裁剪
- 代码裁减调整至最高等级
- link.xml
团结引擎通过深入分析,脚本代码实际运行时,通常只会用到很少的一部分元数据(反射、或者虚函数调用时访问)。例如,一个数组类型可能包含155个方法和25个虚函数,实现了6个接口,但实际运行时可能只会用到其中一小部分,导致大量内存被余加载。
因此,可以采用延迟加载策略。这意味着只有当游戏真正需要某个元数据项时,才会初始化和加载该数据。这种方法可以显著减少IL2CPP运行时的内存占用。
Unity后处理
- 修改Urp的渲染管线,动态开关渲染特性,渲染特性的资源动态分配&释放
- 重写后处理的框架,内存相关优化代码结构,避免反射进行无效访问
- 动态加卸载用到的资源
配置表
背景
- 1000张配置表
- 内存占用极高
- C#/Lua频繁访问
可选方案
- 存储在单侧Lua/C#
- 混合存储
- C++存储
方案选择
- 配置表全部放到C++
- 生成lua config wrap文件
- 生成c# config wrap文件
- 弱表
- 支持强引用
- C++内存压缩
优势
- C#/lua访问C++非常高效
- 全局只有一份,配置数据零余
- 内存占用更低
- 代码结构更优
C++内存压缩
压缩方法
- 对象池,合并重复单元格
- 位运算,优化列数据量
- int8替代指针引用
- mmap文件映射
- 数据结构优化
- 延迟加载
- ...
场景流式加载
背景
- 1024*1024
- 同屏200W面
- 贴图1024
- 自由视角
美术资产分类
- 微景,装饰物,不影响游戏内容,比如碰撞,导航
- 近景,小型建筑物
- 中景,房屋建筑
- 远景,地形,轮廓,特色标志性建筑
加载策略
- 格子加载
- 分层加载
- 连通图加载
- 自适应加载
- 全局LOD加载
总结
- 精准定位,杜绝主观猜测
- 深入分析,精通业务
- 全量优化,不放过任何一个模块
- 逐个攻克,没有捷径