问题描述

最近项目中一直偶现Native Crash,先看下log。

分析

大概看了下,是libc.so抛出的,再仔细看,可以发现此问题的关键。

文件描述符(fd)超过上限,文件描述符上限这个在不同系统中有不同的定义,在部分Android设备上是1024个。

可以通过这个命令进行查看: ulimit用于限制启动进程所占用的资源,使用-n可以查看每个进程可以打开的最大fd。

这个问题就相当的棘手了,先简单介绍下UNIX系统中的文件描述符。

UNIX系统中,所有文件是通过文件描述符进行引用的,它通常是一个非负整数,标识一个进程正在进行访问文件。

下面我们查看当前进程的fd使用情况。 首先找到pid

查看进程fd占用

ls-l查看所有已占用的fd资源

统计总的占用情况

表示当前进程一共占用了153个fd。

解决

随后逐渐定位问题,发现一些场景,如列表滑动,会造成fd一直增长,没有释放。

经过排查,问题出现在OkHttp的连接没有关闭。应该这样改正。

我们看下OkHttp源码,为什么Response不Close会造成泄漏。

如果ResponseBody不进行close的话最终会导致SteamAllocation中的streamFinished没有调用,导致Socket没有关闭。

总结

file,socket,pipe之类的fd资源需要及时关闭,否则会引起Native层的Crash,并且问题极难排查。

通过/proc/<pid>/fd/目录下的文件,查看fd的占用情况。

参考资料:

https://github.com/square/okhttp/issues/2232 https://gist.github.com/jhansche/322965fa3c3a6179114bc3ac8e4337ec#file-watch-fds-sh https://stackoverflow.com/questions/30521826/fortify-source-fd-set-file-descriptor-fd-setsize-calling-abort

发表评论

电子邮件地址不会被公开。 必填项已用*标注