接手老项目(历史遗留下来的bug)
这个项目跑的是rk3288的板子
adb检验应用包名是否为句柄泄露
进入adb shell root
C:\Users\32773>adb shell
shell@rk3288:/ $ su
查看每个进程最大句柄数
root@rk3288:/ # ulimit -a
- 上面可以看到每个进程的最大句柄数是1024个,超过这个数量,程序就会闪退
查看app包名的pid
ps | grep 你的app包名
查看pid为3617的当前句柄数
ls -l /proc/3617/fd | wc -l
- 如果怀疑程序是句柄泄露,则每隔一段时间运行以上命令,看句柄数是否逐步增加,如果出现句柄数一直往上涨,则可以断定程序出现了句柄泄露。当句柄数达到1024时,程序就会崩溃
列出句柄被占用详细情况
ls -l /proc/3617/fd
如果句柄数一直呈上涨的趋势,达到1024系统就会直接关闭进程,crash是获取不到错误信息的
这是我的应用包名获取到的句柄详情
- 可以看到socket占用了大部分的句柄数,正常来讲不会出现这种情况。
由此可以看得出导致句柄泄露的原因是网络请求,所以重点就要排查网络请求。
由于我们客户端和服务器进行连接的方式是轮询http的方式,并没有使用socket和服务器进行长连接,刚开始也觉得很奇怪,明明就没有使用socket,但是为什么句柄数大部分都被socket所占据。我就从我们轮询的接口开始。很幸运,在排查的过程中,终于找到了问题所在。首先我暂停轮询接口,只执行一次接口,然后在adb里面查看句柄数有没有再次增加,发现句柄数稳定在67,经过很长一段时间都稳定在67,证明找对了,就是这个接口导致的句柄泄露。我再次打开轮询,注释掉获取接口数据后的所有代码,再次查看句柄数,发现句柄数又是飙升,又缩短了问题所在,出现问题就是在调用接口之前,初始化数据所导致的句柄泄露。终于,在代码中找到机器码使用的是native c++写的,终于知道为什么是socket占据句柄数了,所以我稍微改了一下代码,只要获取了一次机器码,就不再走native获取机器码方法。再次查看句柄数,句柄数稳定在67了,经过很长一段时间都稳定是67了,终于解决了这么难搞的句柄泄露。