浅谈FD泄漏
内容提要
FD是文件描述符,用于唯一标识进程所打开的文件、管道或网络连接。在Android中,文件也可以是打印机、硬盘或网络接口。当进程打开或创建文件时,内核会返回一个fd。FD泄漏会导致进程崩溃。常见的泄漏场景包括输入输出流、Socket和Cursor等。处理方法包括及时释放资源和使用StrictMode进行排查。可以通过ulimit -n命令查看进程的最大可持有FD数量。
延伸解读
FD泄漏为何不常见但需警惕
每个进程可持有的FD数量有限,例如Redmi Note 10 Pro上为32768,足以应对大多数非极端情况,因此FD泄漏问题并不常见。然而,一旦泄漏累积超过上限,应用会立即崩溃。开发者不应因问题少见而忽视,尤其在长时间运行或频繁创建资源的场景中,需保持警惕。
HandlerThread与FD的1:1:1关系
每启动一个HandlerThread,就会创建两个FD:anon_inode:[eventfd]和anon_inode:[eventpoll],用于线程通信。因此,HandlerThread、eventfd、eventpoll的数量呈1:1:1关系。若发现eventfd和eventpoll数量异常且相等,可初步定位为HandlerThread未释放导致的泄漏。及时调用quitSafely()或quit()可避免FD增长。
弹窗泄漏:每个Dialog约12个FD
弹窗也可能导致FD泄漏。示例中,弹出100个AlertDialog后,FD数量从100激增至1300,相当于每个Dialog产生约12个FD。这提示开发者,弹窗使用后应及时关闭,避免累积。可通过dumpsys window命令查看与窗口相关的FD,辅助定位此类泄漏。
排查FD泄漏的实用工具
排查FD泄漏可借助StrictMode检测主线程不当读写文件和Socket;通过ls -l /proc/${pid}/fd查看FD详情,并用awk和uniq统计各类型数量;线上监控FD数量,达到警戒值时上传/proc/${pid}/fd内容分析。结合日志中循环打印的Socket创建失败等信息,能更高效定位问题。
Q&A
什么是文件描述符(FD)?
文件描述符(FD)是一个非负整数,用于唯一标识进程所打开的文件、管道或网络连接。
FD泄漏会导致什么后果?
FD泄漏会导致进程崩溃,因为一个进程能持有的FD数量是有限的,超出最大持有数后,应用会崩溃。
如何检查进程的最大可持有FD数量?
可以通过执行命令ulimit -n来查看进程的最大可持有FD数量。
常见的FD泄漏场景有哪些?
常见的FD泄漏场景包括输入输出流、Socket和Cursor等。
如何处理FD泄漏问题?
处理FD泄漏的方法包括及时释放资源和使用StrictMode进行排查。
如何使用StrictMode排查FD泄漏?
可以通过设置StrictMode的线程策略和VM策略来检测文件读取、写入和Socket使用等问题,从而排查FD泄漏。