打破重重阻碍,手淘如何突破native crash提升稳定性?

简介: 本文是作者在 「Top100全球软件案例研究峰会」上分享的——手淘Native治理,结合分享后的反馈焦点,从 native 问题线下发现和快速定位、新so集成标准、线上历史native问题治理等几个方面为大家介绍,特产此文。

屏幕快照 2020-03-04 下午4.07.12.png

作者|潘文超(开风)
出品|阿里巴巴新零售淘系技术部

导读:本文是作者在 「Top100全球软件案例研究峰会」上分享的——手淘Native治理,结合分享后的反馈焦点,从 native 问题线下发现和快速定位、新so集成标准、线上历史native问题治理等几个方面为大家介绍,特产此文。

扫描下方二维码,关注「淘系技术」微信公众号,回复“native”即可获取本次分享完整版 PPT 资料!

qrcode_for_gh_4b3f15bce4d8_258.jpg

背景

屏幕快照 2020-03-04 下午4.09.53.png

无线客户端 crash 一般分为 java crash 和 native crash ,无线应用往往为了追求更好的性能,把一些复杂的计算放到 native 层去实现,java 层通过 jni 调用 native 层实现,满足功能场景;在 native 层产生的崩溃就产生了 native crash ;无线客户端衡量稳定性的最重要的指标就是 crash 率,稳定性一直是各系统治理的重中之重,也是一直绕不开的话题,而 native 是目前业界认为治理最有难度,也是要重点突破的方向。接下来分析一下为什么 native 治理值得去做以及如何做好。

▐ 目前手淘Android的crash现状——找方向

从图中我们可以看出,java crash 正常可以维持在较好的水平,手淘 native crash 一般比 java crash 要高,大促期间,由于手淘内存瓶颈, native crash 率会涨到日常水准的2-3倍。

从数据可见,native crash 是 java crash 的6倍之多,如果要想进一步突破,native 是有很大空间的,但 native 问题一般都很难定位, 堆栈不全,或者堆栈都集中在系统 so 上,无法直接定位问题,所以想要突破难度很大。手淘稳定性再上升一个台阶,native crash是瓶颈,需要突破。

▐ native crash 治理挑战——难

屏幕快照 2020-03-04 下午4.10.36.png

(1)难点一:crash堆栈目前绝大部分只有系统so,缺乏问题关联的业务模块so,定位问题难度大,可以看一下如下的一个native crash堆栈,堆栈中的so都是系统的,无法直接定位业务问题。

(2)难点二:线上so都是去符号化的,即使堆栈中有业务so,也需要记录该APP版本对应的符号化so做反解才能拿到能看得懂的堆栈。这点已经通过第一阶段的native工程标准化解决,打出来的SDK包里面必须要有对应的符号化so才可以集成。

(3)难点三:目前线下有效提前发现native问题的手段缺乏,想要提前发现,需要平台工具和有效手段。

▐ native crash 治理核心问题是什么?——找抓手

要治理、要解决问题,首先得理清目前导致 native crash 的问题,在做之前,做了一下 crash 数据分析,于是手动捞取了当时近5个版本的 top native crash 数据,占比最多的就是sig 6和sig 11。

那能说明什么问题呢?signal 6这种崩溃信号要看具体场景,但根据具体数据分析,手淘里面一般都是堆栈溢出、OOM 等导致的。signal 11 这种崩溃基本就锁定为内存问题了。

根据实际数据,大部分 crash 原因是因为内存,可以初步下的结论是,目前手淘 native crash 治理的关键是内存,解决手淘native内存相关的问题即可解决掉不部分问题。

Native问题治理平台工具调研

对集团内及业界的一些产品做了一些调研,详细如下:

屏幕快照 2020-03-04 下午4.11.04.png

分别从使用成本、功能支撑、是否有堆栈能力,性能如何等维度进行了比较,其实我们的诉求是希望不需要 root 就能 run 起来,因为我们要持续集成、线上能灰度验证,线下可以大规模任务执行、并且可以做手淘 native 问题沉淀,能把问题沉淀做成检查项,可以涵盖解决主要的内存问题,不止是内存泄漏。因此开发了Native Finder,希望能彻底治理好手淘 Native 问题。

Native治理——Native Finder整体技术方案

Native Finder是利用elf hook的原理,对malloc、free、realloc、alloc、mmap、munmap 等操作进行 hook,在自己的 hook 函数中,做一些智能分析和统计,并最后会调用系统内存操作函数,不破坏 so 原本发起的 malloc 等操作。

这个方案的缺点是会有一定的性能损耗,毕竟在 malloc 等操作中增加了一些分析和统计操作,但性能影响还好,在开了堆栈能力之后,APP性能会受影响,这个也是后面要优化的地方。整体技术方案如下:

屏幕快照 2020-03-04 下午4.11.46.png

native crash治理过程

屏幕快照 2020-03-04 下午4.12.22.png
首先在前期,花了比较多时间去研究历史数据及问题,认真分析 crash 的关键问题和痛点是什么,才找准了方向,分析出来内存问题是最痛的点。治理过程总结如上图,分为5个阶段。接一下讲详细介绍结合Native Finder工具平台的治理过程和心得。

▐ native工程标准化

治理总结如下:

屏幕快照 2020-03-04 下午4.12.48.png

总结起来这个阶段我们做了3件事情:

第一,库迁移,为什么要做库迁移呢?我们把老的gnu C++基础库迁移成libc++_ shared库,所有so都做统一,归一化,方便归一native层问题;

第二,我们还做了重复so治理,因为不同so可能依赖了相同的so基础库,举个例子,例如A so依赖了libopenSsl基础so,B so也依赖了libopenSsl库,但他们依赖的版本不同,这样带来的坏处是,首先会增加包大小,其次会有相同so的不同版本存在应用中,这给定位问题带来了麻烦,所以需要对基础so去重。

第三,每个版本包包括灰度版本都需要存储下对应的符号化so,便于在crash发生后,我们对堆栈做符号化处理,这样堆栈我们就能看懂了,加快和精准定位问题。这个阶段是后面做的所有事情的基础,非常重要。接下来我们看看下一个阶段治理

▐ Native Finder开发完成,线下monkey跑native问题

屏幕快照 2020-03-04 下午4.13.44.png

此阶段发现了几个堆破坏的问题,但是经过好几天反复线下执行 monkey,并未有任何进展。

后续调整思路,开始逐个分析线上存在的 native crash,并根据这些 crash 特征和根因开始沉淀经典问题,并把这些问题做成检查项,跟同学交流和对焦后。

通过进一步的数据,发现内存 OOM 是目前优先级较高,且比较严重的问题,所以开始做这方面的技术建设,跟 crashSDK 打通,Native Finder 中统计和分析 so 维度占用内存未释放的数据,在 crash 的时候做内存信息 dump,并输出辅助信息,例如 malloc、mmap 次数、大内存(大于2M,属于大内存申请,可配置,可动态调整)的申请等信息。接下来看一下线下monkey 驱动阶段

▐ 线上灰度,结合用户真实操作场景crash

屏幕快照 2020-03-04 下午4.14.06.png

线下 monkey 并不能都能复现问题,借助工具平台拿到关键信息去做问题解决和定位,我们希望场景更加丰富和多样,所以我们把 Native Finder 放到线上,做了线上灰度。

随即把 Native Finder 放到线上做外灰,在用户真实操作场景下的 crash,拿到 crash 时的内存 dump,但是经过一段时间的线上 crash 内存信息采集,然后分析之后,没发现明显问题,从现在回头看这个阶段,其实当时的数据是能够体现出问题的,只是当时的想法不对。

▐ 虚拟内存不足,是目前OOM主要原因

我们对线上crash做了分析,同时也在线下做了可疑场景的尝试复现,复现过程中,我们也做了大量数据的对比分析;

分析发现:正常 crash 跟 native oom crash,在内存详细数据上做对比,发现OOM crash 在 native vmsize 上有较大差异,又看了很多手淘 OOM crash,发现都是这个原因,vmsize 暴涨。

大家都知道,32 位系统下,系统 vmszie 只有4G,还要抛去一些系统内核占用、以及共享内存占用,vmsize比较有限,手淘又是一个体量很大的航空母舰,各个业务都想有最佳的业务体验,都想用空间换时间,每个业务泄漏那么一点,那手淘就被撑爆了,是累加泄漏的结果。

所以手淘 Android OOM 要一个一个解决,逐个挖出来,才能根治。我们整个过程沉淀了如下检查项:一共沉淀了8项内存检查,内存检查项已经能覆盖 80% 以上的内存问题了;fd 文件句柄检查项一共沉淀了6项,fd 的检查项已经能覆盖几乎95%以上的 fd 问题了。

我们同时也研发了本地调试模式,方便开发和测试同学,能快速在本地复现和定位问题,具体的技术方案如下:

屏幕快照 2020-03-04 下午4.14.06.png

▐ 开始陆续发现各种 native 问题

朝着这个方向,对 Native Finder 做了逐步优化,开始陆续发现各种问题,治理初步阶段,我们通过 Native Finder 工具平台一共治理发现 20+ 问题,其中包括了多种问题类型,例如内存堆破坏、内存泄漏、OOM、内存操作越界、多次free、内存操作错误等。

同时手淘日常的 native crash 率也有明显降低。到这里,我们 native crash 已经初见成效。虽然通过治理,陆续发现了不少问题,但是还远远不够,手淘内存问题依然严峻,特别是双十一场景下,互动、活动以及各种场景链路互拉的场景,内存问题还是很严峻,后续还需更加努力。

展望

接下来我们希望还能做的更多,现在才刚刚开始;手淘内存问题依然严峻,要彻底治理,需要建立卡口,发现问题自动加入必改问题池,形成良性循环,旧问题不断发现解决的同时,还需要杜绝新问题的引入。

除了 native so 导致的内存问题,当前 H5 场景的内存问题也比较严峻,去手淘随便拿几个 H5 页面,看一下内存增量,都超过内存标准,H5缺乏管控,下半年需要对H5内存做卡口严控;目前针对前端的内存泄漏,还没有有效的手段去检测发现,从native层看,都体现在内核上,内核应该是没有问题的,如果有效发现前端代码导致的内存泄漏,也是一个值得研究的点,不过先做卡口再做进一步突破。

屏幕快照 2020-03-04 下午4.16.08.png

今日吐槽

大家都在 native 治理上遇到哪些坑?
欢迎评论区留言,和小橙子分享哦~

We are hiring

淘系技术质量团队负责保障整个淘宝和天猫主站的业务质量,在这里有丰富多样的业务场景和技术挑战,以及很多优秀的合作伙伴。在这里你不仅能够了解世界级双十一是如何保障的,最关键的是有对技术极致追求,对生活的充满热爱的一群俊男美女们。
还等什么,赶紧加入我们一起共同打造淘系的技术质量。
请投递简历至邮箱:hane.yjr@alibaba-inc.com

关注【淘系技术】,一个有内容,有温度的微信公众号!

屏幕快照 2020-02-07 下午3.57.54.png

相关文章
|
2月前
|
机器学习/深度学习 人工智能 监控
提升软件质量的关键路径:高效测试策略与实践在软件开发的宇宙中,每一行代码都如同星辰般璀璨,而将这些星辰编织成星系的过程,则依赖于严谨而高效的测试策略。本文将引领读者探索软件测试的奥秘,揭示如何通过精心设计的测试方案,不仅提升软件的性能与稳定性,还能加速产品上市的步伐,最终实现质量与效率的双重飞跃。
在软件工程的浩瀚星海中,测试不仅是发现缺陷的放大镜,更是保障软件质量的坚固防线。本文旨在探讨一种高效且创新的软件测试策略框架,它融合了传统方法的精髓与现代技术的突破,旨在为软件开发团队提供一套系统化、可执行性强的测试指引。我们将从测试规划的起点出发,沿着测试设计、执行、反馈再到持续优化的轨迹,逐步展开论述。每一步都强调实用性与前瞻性相结合,确保测试活动能够紧跟软件开发的步伐,及时适应变化,有效应对各种挑战。
|
3天前
|
监控 项目管理
产品经理如何打破外委项目瓶颈?掌握这5个策略
本文探讨了产品经理在外委项目管理中的关键角色与挑战,提出了明确项目角色责任、科学规划项目进度、加强与业务方沟通、建立风险管理机制及使用高效项目管理软件等策略,以确保项目顺利推进并按时按质交付。
|
3天前
|
数据挖掘 项目管理
打破传统管理瓶颈,6个技巧让项目顺利交付!
本文探讨了在快速变化的商业环境中,如何通过现代项目管理思维与工具提升项目执行效率和团队协作水平。文章详细介绍了项目管理的定义、核心思维、具体步骤及工具应用,强调了明确目标、任务分解、实时跟踪、跨部门协作、风险管理与成果复盘的重要性。通过这些方法,团队可以更高效地完成项目,避免传统管理中的常见问题。
|
5月前
|
Android开发 开发者 容器
跨端技术问题之碎片化对开发者有什么直接影响
跨端技术问题之碎片化对开发者有什么直接影响
|
5月前
|
移动开发 小程序 JavaScript
跨端技术问题之小程序渠道环境的差异带来了什么样的挑战
跨端技术问题之小程序渠道环境的差异带来了什么样的挑战
|
4月前
|
存储 开发工具 git
Flutter相关痛点解决问题之保证共建开放性的同时确保软件整体的质量和性能如何解决
Flutter相关痛点解决问题之保证共建开放性的同时确保软件整体的质量和性能如何解决
|
4月前
|
存储 运维 Cloud Native
核心系统转型问题之系统建设实施中,巴别塔现象如何避免,如何提高工程效率和实际效果
核心系统转型问题之系统建设实施中,巴别塔现象如何避免,如何提高工程效率和实际效果
|
4月前
|
开发框架 缓存 Android开发
Flutter相关痛点解决问题之研发环境与工程管理中的配置难题如何解决
Flutter相关痛点解决问题之研发环境与工程管理中的配置难题如何解决
|
4月前
|
NoSQL 关系型数据库 MySQL
做电商业务开发这几年,我学到的系统稳定性建设方法
文章总结了电商业务开发中保障系统稳定性的关键方法,包括代码健壮性、安全变更、系统链路梳理、接口降级与限流、定期降级演练、预案准备、系统压测、日常巡检、中间件巡检、值班制度和告警机制,强调了稳定性建设是一个长期任务,需要持续迭代优化,并保持对生产系统的敬畏之心。
|
4月前
|
缓存 算法 数据库
安卓应用性能优化:一场颠覆平凡的极限挑战,拯救卡顿的惊世之战!
【8月更文挑战第7天】《安卓应用性能优化实战》
53 4
下一篇
无影云桌面