内存优化
管理机制
Android内存分为系统和 V8 两块,两者都沿用了系统原有的内存管理机制
V8 的内存回收机制可以参考https://v8.dev/blog/trash-talkAndroid 系统内存管理机制可以参考https://developer.android.com/topic/performance/memory-overview iOS小游戏在 iPhone 上是沿用了 iOS 系统的内存管理机制
分析手段和工具
性能监控面板在微信 Android 7.0.7 版本及以上,我们在小游戏开发版和体验版提供了性能监控面板,可以通过胶囊按钮打开,效果如下图所示
开发者可以监控不同内存的占用情况,通过不同内存的变化趋势来判断是否有内存泄漏的情况,各个指标含义如下
名称含义summary.native-heapnative 内存summary.system系统内存summary.total-swap总 swap 内存summary.graphics显存summary.java-heapjava 内存summary.total-pss总内存summary.private-other其他私有内存summary.code静态代码,资源内存summary.stack栈内存如果发现内存一直增长,为了排除是 GC 延迟的影响,可以在胶囊按钮中,点击开发调试中的 Request Force GC,会去立即调用一次 GC,以此对比内存的真实增长情况。
Heap Snapshot除此之外,微信 Android 7.0.7 版本及以上,我们在小游戏开发版和体验版提供了 Heap 内存快照的能力,同样是在胶囊按钮中打开,选择开发调试中的 Take Heap Snapshot,在界面弹出如下图所示的提示后,从提示中的位置把 heapsnapshot 拷贝到电脑上
之后在微信开发者工具中的调试器的 Memory 中,Load 拷贝出来的 heapsnapshot 文件,就可以查看 V8 的内存快照了,效果如下图所示
heapsnapshot 的使用方法可以参考
https://developers.google.com/web/tools/chrome-devtools/memory-problems/heap-snapshots
V8-CPU-Profile微信 Android 7.0.7 版本及以上,我们在小游戏开发版和体验版提供了 V8-cpu-profile 的能力,同样是在胶囊按钮中打开,选择开发调试中的 Start CPU Profile,界面上会弹出 “start cpu profiling..” 的提示
之后再在开发调试中选择 Stop CPU Profile,在界面弹出如下图所示的提示后,从提示中的位置把 cpuprofile 拷贝到电脑上
之后在微信开发者工具中的调试器单击右上角三个点的按钮 -> More tools -> JavaScript Profiler -> Load,加载刚才生成的 cpuprofile 文件,就可以查看 CPU 的使用情况了,效果如下图所示
左上角的下拉菜单可以选择如下三种模式:
Chart:显示按时间顺序排列的火焰图。Heavy (Bottom Up):按照函数对性能的影响排列,同时可以检查函数的调用路径。Tree (Top Down):显示调用结构的总体状况,从调用堆栈的顶端开始。这里我们选择 Tree (Top Down) 模式,按 Total Time 降序排列。可以看到有如下三列:
Self Time:函数调用所耗费的时间,仅包含函数本身的声明,不包含任何子函数的执行时间。
Total Time:函数调用所耗费的总时间,包含函数本身的声明及所有子函数执行时间。即:父函数的 Total Time = 父函数的 Self Time + 所有子函数的 Total Time。Function:函数名及路径,可展开查看子函数。具体使用流程可以参考https://developers.google.com/web/tools/chrome-devtools/rendering-tools/js-execution
优化建议
在 iOS 上,当微信客户端在一定时间间隔内(目前是 5 秒)连续收到两次及以上系统内存告警时,会主动进行小程序的销毁,并提示用户 「该小程序可能导致微信响应变慢被终止」。建议开发者注册 wx.onMemoryWarning 监听内存告警事件,并在在收到一次内存告警后,调用一次 wx.triggerGC 清理内存,降低小程序被销毁的概率。在场景切换的时候主动调用 wx.triggerGC。基础库 2.5.0 版本开始支持压缩纹理,其中 iOS 支持 pvr 格式,Android 支持 etc1 格式,压缩纹理可以有效降低图片资源占用内存大小,具体使用方式,可以参考引擎方提供的文档。Cocoshttps://docs.cocos.com/creator/manual/zh/asset-workflow/compress-texture.htmllayaboxhttps://ldc2.layabox.com/doc/?nav=zh-ts-4-14-7
egrethttp://developer.egret.com/cn/github/egret-docs/Engine2D/bitmapTexture/ktx/index.html
需要注意的是,etc1 需要纹理的尺寸是 2 的 n 次幂,同时 etc1 不支持透明图片,但可以通过 shader 等手段达到渲染透明 etc1 图片的目的