一、 起因
前段时间,线程程序运行一段时间,总会莫名出现crash,起初怀疑是内存泄漏或者设备引起的(针对终端设备的Android程序,且刚好换了新的设备,怀疑兼容性没有做好),排查了也没有发现问题。
Bugly捕捉到一个SIGABRT的错误,没有其它有用的信息了:
后来,我们在开发环境中,使用对应版本的程序及终端设备进行模拟测试。注意,设备处于开发者模式,且将调试日志输入开关打开。后面问题复现了,用adb pull /data/logs/ ./命令将日志保存到本地,/data/logs/是我们那个设备系统日志输入的目录。
日志文件夹里面有一个android文件,打开这个文件,找打crash发生的时间点查看日志:
根据日志文件,ashmem_create_region failed for ‘indirect ref table’: Too many open files,由于该进程打开了太多文件,导致了抛出OutOfMemoryError “Could not allocate JNI Env”,所以程序抛出异常。Bugly应该也是将crash信息保存到文件中然后再进行上报,但是程序出现crash的时候恰好发生too many open files的错误,所以Bugly也没有办法将crash信息比较完整的记录下来。
二、分析及解决
使用adb shell连接设备,使用ps查看设备的进程,找到对应程序的进程:
使用ls /proc/pid/fd | wc -l (pid由上面步骤查询到)命令,查看进程最大文件限制
使用ls -l /proc/pid/fd 命令查看5243进程已打开文件的详情
经过一段时间模拟测试后,查看已打开文件及查看已打开文件详情,发现有个文件确实被多次打开而且没有被释放,导致达到阈值后出现crash发生OOM问题。
定位到问题后对USB外接设备相关的代码做相应的优化就解决这个问题了。