原文链接 https://blog.csdn.net/weixin_40137140/article/details/134083407?spm=1001.2014.3001.5501

前言

本篇文章是作者本人通过查看微信unity小程序官方内存优化文档和结合自身项目经验总结所得,会有一定的重复内容,在观看本篇文章之前,请仔细浏览微信官方内存优化文档,否则可能对文章无法理解,如有错误,欢迎指出。

微信unity小程序优化文档:https://github.com/wechat-miniprogram/minigame-unity-webgl-transform/blob/main/Design/OptimizationMemory.md

一.unity小程序内存限制

1.轻度游戏:

进程内存 < 1gbUnityHeap < 300MB

2.中重度游戏:

进程内存 < 1.4gbUnityHeap < 450MB

二.unity小程序内存分布

用作者知道的一个中重度游戏(优化一般)做分析:

1.进程内存详情分析:

UnityHeap占比只有33%,可操作空间不是特别大内存浮动主要是大量特效显示,浏览器无法及时释放内存显存大小并不精准,作者推测所得,实际应该在100~200M之间。WASM编译占比较大,原因是代码和依赖库太多。

2.UnityHeap内存:

缓存空间是用于存储资源对象池,防止资源频繁加载释放,实际资源+缓存空间占比大约在50%。Lua内存和托管堆较大。

3.通过以上信息得出结论:

在进程层面,可以对代码包体,渲染效果,内存浮动方面进行排查优化。在unity业务层,我们可以对资源,Lua和托管堆进行优化。

三.监控工具

unity profiler监听,真机连profiler才准确,编辑器不准确。 目前微信连真机profiler的教程。 工具地址:https://q1doc.yuque.com/kiob3t/gynxh4/eb4qe7lua profiler插件工具地址:https://github.com/leinlin/Miku-LuaProfilerunity 微信转换插件的Profiling Memory 内存分析,具体操作信息看微信内存优化官方文档。

正式包上通过接口获取内存,观察变化,如LuaMemory,NativeReserverd,Total Used Memory进程级别: Perfdog、Android Studio、 Mac Xcode Instrument

三.进程内存

内存分类(照搬微信文档):

基础库+Canvas:在小游戏环境中并不存在DOM,但依然会存在一些基本消耗,比如小游戏公共库,Canvas画布等。典型地,小游戏公共库约占用内存100~150MB,Canvas 画布与设备物理分辨率相关,比如iPhone 11 Promax占用约80MB。 Unity Heap: 托管堆、本机堆与原生插件底层内存。举例,游戏逻辑分配的C#对象等托管内存、Unity管理的AssetBundle和场景结构等本机内存、第三方原生插件(如lua)调用的malloc分配。 WASM编译: 代码编译与运行时指令优化产生的内存,在Android v8、iOS JavascriptCore中还需要大量内存进行JIT优化 GPU内存:纹理或模型Upload GPU之后的显存占用, 由于Unity2021之前不支持压缩纹理,纹理内存会造成明显膨胀。 音频:Unity将音频传递给容器(浏览器或小游戏)后,播放音频时将占用的内存。目前UnityAudio将自动适配微信小游戏,特别地请避免使用fmod播放长音频。 内存浮动:主要是渲染压力大时,浏览器缓存没有及时释放。

获取手段(单位MB):

Unity Heap:微信转换插件的Profiling Memory查看GPU内存:目前作者是通过进程总内存减去其他内存得出WASM编译: 内存大小≈wasm未压缩文件大小*10(注意是未分包情况)内存浮动:可以使用perfDog或者Instrument测试真机情况下进程最大内存峰值时(特效多的时候)调用wx.triggerGC,查看进程内存下降额度,多测几次就大致得出结论。接口文档:https://developers.weixin.qq.com/minigame/dev/api/base/performance/wx.triggerGC.html

优化手段:

GPU内存:主要是显示效果,RenderTexture或者抓屏,shader效果之类入手。WASM编译: 开启unity代码剔除(裁剪)功能,使用微信分包工具**(中重度游戏必须处理)**, XLua Warp生成加上 GEN_CODE_MINIMIZE 宏,减少Warp生成数量,降低代码包大小,微信代码分包地址:https://github.com/wechat-miniprogram/minigame-unity-webgl-transform/blob/main/Design/WasmSplit.md 内存浮动:内存浮动较大的项目可以通过定时调用wx.triggerGC来防止内存突破限制导致崩溃。音频:使用微信音频

四.UnityHeap内存

内存分类:

TotalHeapMemory: UnityHeap总预分配内存大小DynamicMemory:UnityHeap当前使用上限,受MonoHeap与NativeReserverd 等影响,崩溃直接表现值,只会增长不会下降。NativeReserverd:本机堆(Native)内存分配峰值,集中在unity底层自动分配的内存(主要是资源)。MonoHeap: 托管堆当前使用内存,主要是游戏中各种对象相关的实例内存,如C#数组,List之类堆内存,峰值只增不减,峰值就代表当前内存。LuaMemory: Lua内存,属于第三方插件malloc产生。

底层分配器:

绿色为空闲内存或碎片,底层分配器会尽量复用白色为预留部分,可被使用其他颜色,已被业务使用

获取手段(单位MB):

DynamicMemory ≈ MonoHeap + NativeReserverd + 原生插件内存+30,结果是三个加起来峰值最大的时候NativeReserverd = Profiler.GetTotalReservedMemoryLong()*0.00000095367431MonoHeap = Profiler.GetMonoUsedSizeLong()*0.00000095367431LuaMemory = LuaAPI.lua_gc(L, LuaGCOptions.LUA_GCCOUNT, 0)*0.0009765625

优化手段:

DynamicMemory: 使用定时器,每帧通过上面获取手段的计算方式得出当前DynamicMemory的使用大小,然后决定业务层是否要调用内存释放相关操作,防止Dynamic峰值上升。NativeReserverd:通过资源优化,AB卸载资源释放,Resources.UnloadUnusedAssets操作等,下降峰值。MonoHeap:管控峰值,避免某个操作导致内存急速增长,但是过后又释放,会让托管堆在长时间使用率低,峰值高的情况,导致内存浪费,需要注意的是在WebGL 托管堆主动调用GC无效。排查lua内存泄露,错误逻辑(循环溢出)导致的内存溢出或者抓着引用不释放。

排查手段:

使用UnityProfiler和Unity MemoryProfiler检查托管堆与本机堆内存详情。使用LuaProfiler查看Lua内存详情,排查内存异常增长与内存泄露情况。

五.微信平台导致内存上升的操作(一定要避免!!!)

UnityWebRequest(主要是AB资源的Cache)的 下载缓存接口在WebGL平台上会导致内存爆发式增长,缓存的所有文件都会算进运行内存。文档地址:https://github.com/wechat-miniprogram/minigame-unity-webgl-transform/blob/main/Design/OptimizationMemory.md

如下列带Cache的接口:

IO操作,主要集中在后台下载并发过高,文件写入频繁(如日志写入,下载记录写入等操作)导致的内存溢出之类,可以实施的操作有:

增加文件操作句柄接口,防止需要连续写入的文本文件调用WXFileSystemManager.WriteFile频繁创建销毁IO流,速度过慢导致写入数据累积。接口地址:https://developers.weixin.qq.com/miniprogram/dev/api/file/FileSystemManager.open.html写入间隔不能太频繁,写入数据量不宜过大。下载文件也会有IO操作,如果是后台下载之类可以调整并发数。

六.其他一些内存优化方向

微信小游戏纹理压缩,文档地址:https://github.com/wechat-miniprogram/minigame-unity-webgl-transform/blob/main/Design/CompressedTexture.md使用Unity Profiler在真机上排查大资源和废弃资源。使用AssetStudio排查大资源,废弃资源和重复资源。重复资源排查工具地址:https://blog.csdn.net/weixin_40137140/article/details/134082859?spm=1001.2014.3001.5501

增加设置像素比接口,iOS上降低真机像素比,可以有效下降内存,一般设成2就行。

表格数据去重,在小程序上因为内存比较紧张,某些类型的游戏往往表格数据较多,处理不当内存可能会突破100M,无论是存储在C#还是lua上,都应该对数据进行合并,尤其是大量的字符串,具体算法可以结合自身项目发挥。 unity 图片资源格式关闭Read/Write与Mipmap

相关链接

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。