移动性能测试 探秘手淘高可用平台 (二)——性能及稳定性治理方案

安卓绿色联盟 · 2018年12月20日 · 2124 次阅读

本系列文章根据手机淘宝客户端基础架构高级开发工程师非台在安卓绿色联盟开发者大会上的分享,共分三篇,介绍手淘技术团队性能和稳定性系统化提升方案 EMAS-MOTU 的设计原理以及实现思路。

本文将重点介绍手淘高可用平台如何进行性能及稳定性治理。

性能治理

主线程卡顿

主线程卡顿是因为主线程的消息超过阈值,从而导致页面丢帧。手淘通过接管主线程消息的分发机制,获取消息的分发耗时和消息类型,从而定位触发主线程卡顿的具体业务并进行针对性治理。

另外手淘在使用系统的 SharedPreferences 时,发现页面跳转导致界面 ANR 的情况。通过阅读系统源码,发现它在做 Receiver 或者 Service 时会强制把所有 SharedPreferences apply 的内容写入文档,导致 ANR。针对这个问题,手淘重写 SharedPreferences 提升性能,减少了这类 ANR 问题的发生。

image

内存泄漏

手淘团队投入了大量时间对内存泄露进行治理。一方面通过接管系统底层组件的生命周期,当组件的生命周期销毁时,对它进行一个 WeakReference 的引用,然后根据 GC 事件触发情况来判定该对象是否泄漏。另一方面,在 Native 层通过 Hook 操作系统底层 malloc 和 free 方法,计算每一个 so 处理内存的情况,根据 malloc 与 free 差值大小与白名单进行对比判断是否存在内存泄露。

内存使用不当

何为内存使用不当?举个例子,当开发一个大小为 100×100 view,实际却使用了 200*200 甚至更大的 bitmap。比如在系统 drawable 目录下放置一张图片,在高清的设备上展示时,它会根据系统自身的原理对它进行拉伸。这时原本只需要单位 1 的内存(100*100),可能变成单位 16 的内存(400*400),内存的浪费率达到 90% 以上。针对这种情况,手淘做了一个内存使用不当排查插件。

视频也同样存这种问题,在低分辨率设备上播放高质量的视频不仅不会给用户带来更好的体验,还可能让设备出现卡顿。还有就是图片持有的问题,当页面已经沉入栈底,最好不要保留之前页面的图片。这样可以保证有足够的内存给前台页面使用,否则随着页面层级的深入,很容易出现 OOM。

资源泄露

手淘主要通过接管系统底层的 open 和 close 两个 Native 方法函数对资源泄露进行治理。当 open 和 close 没有成对出现,并且该业务并不是伴随整个应用生命周期(伴随整个生命周期的文件有白名单),可以判断该操作可能存在资源泄漏。平台会将该异常行为告知对应的开发同学检查和治理。数据库的治理同样也采用了这套方案。

线程问题

线程问题比较复杂。在线程创建时可能会触发一些意想不到的问题,比如 Out Of Memory error。Out Of Memory error 可能是由线程创建失败导致的。因此,手淘对线程创建进行了接管。业务在创建时,对它的方法调用栈进行聚类,就可以知道每个业务创建的线程数量,以及线程创建是否合理。建议应用开发者在创建线程时一定规范命名,以便快速定位具体的业务方。

流量监控

手淘主要是通过接管 Socket 协议,分析协议头部获取请求和回流数据内容的大小信息进行流量监控治理。如发现异常,可以让开发同学定位解决。同时也可以监听后台流量行为,观察 APP 切到后台以后是否还有大量的网络请求。

image

设备评级

安卓设备百花齐放,手淘对不同的设备采取了计分的方法进行评级,根据设备分数采用不同的策略,展示相应的图片、视频和业务,给用户带来最佳的性能体验。这个设备评级方案可以给开发同学提供指导建议,更好的展现业务形态。

布局性能

在开发的过程中,常常要通过 HierarchyViewer 的方法检查布局结构是否合理。手淘写了一套算法,检查页面结构是否合理,页面层级是否过深、页面层级是否还有继续优化的空间。同时还实现了一套 OverDraw 的算法,给开发同学提示具体哪个层级可以优化,怎么样的降层级,怎么样解决 OverDraw 的问题。

用户体验优化

手淘很关注用户的体验,包括启动时间、每个页面的打开耗时等。通过监控启动时各个子任务的耗时,以及对这些信息快速的分析,判断每一次发版质量变化的具体原因。

4.X 设备体验优化

随着产品功能越来越丰富和产品体积逐渐的壮大,4.X 设备出现了 multidex 越来越慢的情况。基于这个现象,手淘把谷歌的 support multidex 包进行了重构改造。经过重构以后的 support multidex 方案,4.X 设备的 Dex 加载随着 Dex 越来越多,它性能提升越好。

内存容灾

内存容灾手淘一直很关注。当用户使用当前页面时,如果内存不足,手淘期望后台页面可以快速释放内存资源,为前台页面服务。手淘开发了内存容灾插件,监听 JVM 的 GC 事件以及轮寻物理页表计算实际使用物理内存,通过这个计算给手淘的业务方发送对应的内存水位事件,如果是属于非常高危的内存事件,就可以让后台快速的释放缓存资源,从而为可视的页面提供更好的服务。

稳定性治理

稳定性的治理主要是两部分,Java Crash 和 Native Crash。

image

Java Crash 治理

手淘通过接管 UncaughtExceptionHandler,拿到具体的 Java Crash 的信息及它的堆栈来进行 Java Crash 治理。Java Crash 治理还有一个经常遇到的 OOM 的情况,一方面可能是虚拟机的内存不足导致的,另一方面可能是线程创建失败导致的,可以使用前面讲到的线程创建插件解决。

Native Crash 治理

手淘通过捕获信号量的方式对 Native Crash 进行治理。当 Native 发生异常时,创建一个子进程,通过 ptrace 的方式去 dump Native Crash 上下文的线程信息。 基于前面讲到的性能治理方式,OOM 的 Native Crash 可以通过 malloc 和 free 的接管,定位具体是哪个 SO 导致这个问题的发生并进行治理。

下期分享将重点介绍 EMAS-MOTU 热修复方案以及开发流程,敬请期待!

上期回顾

探秘手淘高可用平台(一)——度量指标及数据平台

共收到 0 条回复 时间 点赞
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册