|
|
这个功能,他们测试了三天,没有一次闪退。
一上线,玩家论坛就炸了。
凌晨三点,值班技术员收到了第一条崩溃日志。
第一章:发布首周·未知环境
问:安卓碎片化有多严重?
极为微小的屠龙1.76经典版本,在发布的首个星期之内,总共收集到了437款不一样型号的设备出现报错情况。
当中,联发科芯片的机型所占比例为百分之六十一,华为鸿蒙三点零及以上系统的占比是百分之二十八。
问:为什么不修?
修,需要先复现。没有那款真机,就没办法。
逆向思维的做法是,先从崩溃堆栈里找共性。
经堆栈呈现,百分之九十的崩溃情形聚焦于.so的纹理上传功能。
这个函数,调用了 ES 2.0的扩展接口。
那批老手机上,驱动根本没有实现这个接口。
第二章:版本中段·资源加载风暴
问:卡顿从什么时候开始?
进副本第3秒,帧率从58掉到11。
用抓了一下,发现主线程在等磁盘I/O。
1.76版本的地图贴图没有打包成图集,散文件超过2000个。
问:为什么不改成异步加载?
改了,会改乱怪物刷新逻辑。
经典版里头,核心循环呈现出同步的特性,对于每一个怪物而言小小屠龙经典1.76安卓,其坐标,其掉落情况,其刷新时间,全都紧密绑定于同一条游戏主线程之上。
所以,他们做了另一个决定。
把贴图从PNG转成ETC2压缩格式。
贴图的体积减少了百分之五十七,I/O等待的时间,从每一帧的四十二毫秒,降低到了八毫秒。
ETC2只支持 ES 3.0以上设备。
那些只支持2.0的老机器,直接黑屏。
这时候需要回退方案。
运行时检测GPU能力,降级使用原始PNG。
加上这个分支判断,代码量增加了300行。
第三章:稳定后期·内存泄漏的真相
问:长尾问题是什么?
玩2小时后,内存占用从180MB涨到1.2GB。
不用MAT工具,光看log就能发现。
每次释放怪物的函数,没有把指针置空。
C++层的std::里还留着已删除对象的地址。
但下一个怪复用的时候,它试图去访问那片已经还给系统的内存。
问:为什么测试没测出来?
那个自动化测试运行的是单个副本的循环,每一次结束的时候就会重新启动。
玩家实际行为是挂机一整天,不关后台。
逆向思维:不是泄漏频率高,而是触发放置条件太简单。
他们改了一个配置。
将怪物复用的最大缓存数量从无限制改为32个。
超过32个,强制调用垃圾回收并重置。
内存峰值从此锁定在380MB。
三个月往后,那个在凌晨三点的时候收到崩溃日志的技术员呀,又一次收到了另外一条日志。
有一种型号,它是三星 S24 Ultra,它基于 16。
原因致使崩溃,乃是.so寻觅不到。
他查了一下。
ES 4.0废弃了该函数,将其改成了。
经典1.76的代码里,没有这个适配。
他点了一支烟。
然后打开了古老的反编译工具。 |
|