一个人可以做几个网站负责人,玉环哪里有做网站,搜索引擎优化简称,wordpress安装 用户名已存在一、背景
崩溃(Crash)#xff0c;即闪退#xff0c;多指移动设备#xff08;如iOS、Android设备#xff09;在打开/使用应用程序的过程中#xff0c;突然出现意外退出/中断的情况。如果App线上版本频繁发生崩溃#xff0c;会极大地影响用户体验#xff0c;甚至导致用户…一、背景
崩溃(Crash)即闪退多指移动设备如iOS、Android设备在打开/使用应用程序的过程中突然出现意外退出/中断的情况。如果App线上版本频繁发生崩溃会极大地影响用户体验甚至导致用户流失以及收益减少。因此崩溃问题是客户端稳定性团队需要重点解决的问题。
然而对于所有崩溃场景仅25%的崩溃可通过信号量捕获实施相应改进另有75%的崩溃则难以识别从而对App的用户体验造成了巨大的潜在影响。
Facebook的工程师将App退出分为以下6个类别 1.App内部主动调用exit()或abort()退出 2.App升级过程中用户进程被杀死 3.系统升级过程中用户进程被杀死 4.App在后台被杀死 5.App在前台被杀死且可获取堆栈 6.App在前台被杀死且无法获取堆栈。
对于第14类退出属于App的正常退出对用户体验没有太大影响无需进行相应处理对于第5类退出可通过堆栈代码级定位崩溃原因对此业界已形成比较成熟的解决方案推荐免费试用阿里云的崩溃分析服务即可快速定位、解决此类崩溃问题对于第6类退出可能的原因很多包括但不限于系统内存不足时继续申请内存、主线程卡死20s以上、CPU使用率过高Stack Overflow等在此我们统一称之为iOS客户端的“Abort问题”。
Abort问题无法被堆栈捕获且发生频次远高于可被捕获的崩溃下称“堆栈崩溃”。从历史数据来看手淘电商类超级App代表的Abort问题数量一般是堆栈崩溃数量的3倍左右优酷Pad视频类超级App代表的Abort问题数量一般是堆栈崩溃数量的5倍左右。可见Abort问题对用户的使用体验造成巨大影响。
本文将针对iOS客户端的Abort问题进行根因定位分析并提出系统性解决方案。
二、Abort问题的原因分类
形成Abort问题的原因主要包括以下4个。
2.1 内存Jetsam
移动端设备的物理内存资源紧张但App仍不断申请内存。因此系统signal 9杀死进程造成异常退出。
{
memoryPages : { active : 24493, throttled : 0, fileBacked : 24113, wired : 13007, anonymous : 12915, purgeable : 127, inactive : 10955, free : 2290, speculative : 1580
},
uncompressed : 125795,
decompressions : 143684
},
largestProcess : Taobao4iPhone,
processes : [
{
...
{ rpages : 2050, states : [ frontmost, resume ], name : Taobao4iPhone, pid : 1518, reason : vm-thrashing, fds : 50, uuid : 5103a88a-917f-319e-8553-c0189dd1abac, purgeable : 127, cpuTime : 4.619693, lifetimeMax : 3557
},
...
}
2.2 主线程死锁
A/B两个线程同时等待对方完成某些操作因而无法继续执行形成死锁造成异常退出。
Exception Type: 00000020
Exception Codes: 0x000000008badf00d
Highlighted Thread: 0Application Specific Information:
com.myapp.myapp failed to scene-create in timeElapsed total CPU time (seconds): 4.230 (user 4.230, system 0.000), 10% CPU
Elapsed application CPU time (seconds): 1.039, 3% CPUThread 0 name: Dispatch queue: com.apple.main-thread
Thread 0:
0 libsystem_kernel.dylib 0x36360540 semaphore_wait_trap 8
1 libdispatch.dylib 0x36297eee _dispatch_semaphore_wait_slow 186
2 libxpc.dylib 0x364077b8 xpc_connection_send_message_with_reply_sync 152
3 Security 0x2b8dd310 securityd_message_with_reply_sync 64
4 Security 0x2b8dd48c securityd_send_sync_and_do 44
5 Security 0x2b8ea452 __SecItemCopyMatching_block_invoke 166
6 Security 0x2b8e96f6 SecOSStatusWith 14
7 Security 0x2b8ea36e SecItemCopyMatching 174
2.3 启动/重启超时
App由于启动/重启的时间超过系统允许的时间限制造成异常退出。
scene-create watchdog transgression: app exhausted real (wall clock) time allowance of 19.93 seconds, Elapsed total CPU time (seconds): 21.050 (user 21.050, system 0.000)
2.4 CPU打爆
主线程死锁、启动/重启超时都可能间接导致CPU打爆造成异常退出。
三、Abort问题的根因定位
Abort问题常常没有明显线索进行问题定位因此解决难度比较大。手淘曾经历过很多次Abort问题数量飙升但无从下手的事故甚至还有一两次发生在双11前不久但往往以“一群人苦逼的众测复现、复现之后也无法确定是否真的复现”收场。
因此我们迫切需要基于已有经验形成一套完整的解决方案快速、准确地定位/解决问题。这就需要我们从以下几个方面着手进行考虑 1.Abort问题发生的场景例如哪个页面、什么操作。 2.Abort问题发生的原因例如内存Jetsam、主线程死锁、启动/重启超时、CPU打爆。 3.对于内存Jetsam需进一步定位到是否发生了内存泄露以及泄露的循环引用Retain Cycle。 4.对于主线程死锁需进一步定位到卡死的堆栈。 5.对于启动/重启超时以及CPU打爆需进一步定位到堆栈。
接下来我们以手淘的主线程死锁问题为例进行根因分析。首先来看一下某版本手淘Abort问题数据的总体视图
由于Abort问题出现之前内存、CPU使用量正常因此初步判断造成异常退出的原因为主线程死锁。
查看相关日志文件验证时间、线索吻合因此可最终确定造成异常退出的原因为主线程死锁。
四、Abort问题的系统性解决方案
4.1 Abort系统性解决方案难点现场捕获
为实现Abort问题的系统性解决方案需充分考虑以下问题 1.通过signal 9杀死进程造成的Abort问题往往难以通过信号量捕获至堆栈。在这种情况下应如何尽可能完整地捕获崩溃现场的关键信息具体包含哪些信息 2.App崩溃时系统处于极不稳定的状态应如何保证崩溃现数据稳定落盘 3.在信息采集、数据捕获的过程中需对大量数据进行写入操作应如何保证日志高性能写入 4.在数据量较大的情况下数据的存储、上传可能对系统造成较大压力应如何保证数据的高压缩率
基于以上考虑我们提出并设计了一套基于mmap的高性能、高压缩率、高一致性、可自解释的trace文件协议作为iOS端高可用体系的数据载体。
4.1.1 mmap数据存储层保证数据写入的高性能和高一致性
1.通过mmap将一个文件或者其它对象映射到进程的地址空间对内存的操作会由内核将数据写到对应的磁盘文件上数据写入的性能与内存操作相当略比内存操作高 2.用户进程崩溃之后这块映射区仍由内核管理可以保证数据的一致性
4.1.2 二进制编码协议保证数据压缩率最高
1.具体编码协议 2.实测编码在压缩率能达到80%以上或者直观一点说使用50k的内存可以记录下用户二十分钟内详细的使用记录包括页面访问记录、系统事件、秒级别的内存、CPU数据。
4.1.3 尽可能多的记录系统多维度指标及异常事件
包括 1.性能数据包括CPU、内存数据用于判断应用当前是不是处理overload状态 2.大内存申请 3.Retain Cycle用于定位Jetsam Event 4.卡顿用于定位watch dog kill 5.当前存活VC实例数量
五、总结
在App的世界里功能层面的差异已经越来越难以体现。在这种情况下良好的用户体验往往是App致胜的关键。而Abort问题对于每一个App而言都是对用户体验的最大挑战需要App开发者给予足够的重视。 原文链接 本文为阿里云原创内容未经允许不得转载。