事情的起因的QA压测过程发生进程号变更,怀疑APP被杀掉过,于是开始看日志
- APP的压测平台会上报进程号变更时间点,发现是在临晨12:20分,先大概确定在哪个日志文件去找关键信息
- 一开始怀疑是crash,然后就在日志中过滤crash关键字,过滤出日志
BroadcastQueue: Can’t deliver broadcast to com.baidu.launcher (pid 951). Crashing it
ProcessRecord: ProcessRecord.kill, reason = scheduleCrash for ‘can’t deliver broadcast’ failed noisy = true killedByAm = false pid = 951 com.baidu.launcher
目前来看是由于广播发不出去导致系统kill了APP
于是先网上搜了下scheduleCrash看下是否有前人的智慧留存,运气不错,有相似情况,原因是Binder通信申请内存不时候内存不足导致的报错
https://cloud.tencent.com/developer/article/1639706
于是下一步就过滤binder关键字
依然是看kill前后时间段的binder打印
JavaBinder: !!! FAILED BINDER TRANSACTION !!! (parcel size = 124)
有很多这个打印,这个是什么时候打印的呢,查了一下JavaBinder,发现没有这个类,网上搜了下
https://blog.csdn.net/xiaoxiaosunzhao/article/details/107325352
发现这个打印是在android_util_Binder.cpp,于是用Google提供的在线源码查看工具Android Code Search搜了下,发现打印位置
报这个错误的时候根据代码逻辑,有2个原因,一个是binder transaction失败而且传递数据大小超过限制 200*1024 也就是200KB, 还有一个就是AIDL接口服务挂了,那么现在就可以过滤下是哪个原因
TransactionTooLargeException
DeadObjectException
通过过滤这两个关键字,发现是第二个原因
问题处在BtGatt,这是BLE蓝牙的相关打印,结果压测场景是按住遥控器说话(这个过程会通过遥控器收音,发送语音数据给设备),所以确定是这个操作引发。这个内存不足的猜想,要么是每次传递数据过大,要么就段时间传递的太多了,导致这时候广播通知,跨进程发现共享内存不足,kill APP,通过Log发现parcel size = 160字节,应该不是太大导致,于是开始查看传递次数,发现出问题这次,收音持续了10分钟多,远超过脚本设定的每20S,收音2S的情况。但是也考虑到这种异常情况和binder传递数据的限制,决定加上了收音时间限制和数据积攒一定数量再发送一次的操作,降低跨进程频率。
根据我们技术负责人的指点,我们framework修改过binder同时工作的数量上限,但是由于系统没有家这方面的打印,也不确定是否是超上限了,所以同时多了降低传输频率的操作