安卓文件描述符泄漏调试

6

在我们公司,我们有很多运行在虚拟/真实设备上的UI测试。测试经过一段时间后会随机崩溃,我认为这是文件描述符超限的结果:我使用了

ls /proc/${PID}/fd | wc -llsof -p ${PID},但它并没有帮助很多——lsof中的大部分行看起来像:

30015    u0_a104  678      sock                                    859560 socket:[859560]
30015    u0_a104  679      0000                0,8                 4539 anon_inode:[eventpoll]
30015    u0_a104  680      0000                0,8                 4539 anon_inode:[eventfd]
30015    u0_a104  681      0000                0,8                 4539 anon_inode:[eventfd]
30015    u0_a104  682      0000                0,8                 4539 anon_inode:[eventpoll]
30015    u0_a104  683      0000                0,8                 4539 anon_inode:[eventfd]
30015    u0_a104  684      0000                0,8                 4539 anon_inode:[eventpoll]
30015    u0_a104  685      0000                0,8                 4539 anon_inode:[eventfd]

所以我的问题是:是否有任何与Android/Java/Linux相关的工具或实用程序可以找到泄漏的源头P.S. System.gc()没有起到作用。

你正在泄露文件、套接字或选择器。 - user207421
1
是的,但 Java 中哪些类使用它们?如何找到它们? - Art
1个回答

8

我已经研究了一段时间这个问题,并想分享我所发现的:

  1. 在Android中,文件描述符至少用于以下用途:

    • 网络套接字(或其他类型的文件)
    • 映射到内存文件
    • 线程 - 这就是我的情况。请参见下面的原因
  2. 如果您创建了HandlerThread,则即使最后一个与HandlerThread实例的链接消失,线程仍将工作并消耗FileDescriptor

  3. 在Android中,可以看到线程:

    • 在Memory Abalyze Tool中的“Java堆转储”中 - 因此,在运行intsrumentation测试时,我看到了> 500个线程 - 它们“吃掉”了所有文件描述符
    • 通过Android设备上的终端adb shell ps -t或只需ps -t

1
另一种查看线程的方式是通过Android Studio的CPU分析器。 - black

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接