fcntl(F_DUPFD_CLOEXEC) error: Too many open files 安卓错误定位

1.分析安卓源码可知,该错误是因为app同时打开的文件过多导致,安卓系统默认同时打开文件数量最多为 1024个,可以通过以下命令查看:

ulimit -a 

得到结果:

-t: time(cpu-seconds)     unlimited
-f: file(blocks)          unlimited
-c: coredump(blocks)      0
-d: data(KiB)             unlimited
-s: stack(KiB)            8192
-l: lockedmem(KiB)        64
-n: nofiles(descriptors)  1024
-p: processes             3711
-i: sigpending            3711
-q: msgqueue(bytes)       819200
-e: maxnice               40
-r: maxrtprio             0
-m: resident-set(KiB)     unlimited
-v: address-space(KiB)    unlimited

2.也可以用以下函数打印出当前系统配置的同时打开文件数量的最大值:

    public static int getMaxOpenFiles() {
        RandomAccessFile randomAccessFile = null;
        try {
            randomAccessFile = new RandomAccessFile("/proc/" + android.os.Process.myPid() + "/limits", "r");
            String line;
            while ((line = randomAccessFile.readLine()) != null) {
                if (line.contains("Max open files")) {
                    line = line.replace("Max open files", "")
                            .replace("files", "").trim();
                    String[] split = line.split(" ");
                    for (String item : split) {
                        if (!TextUtils.isEmpty(item)) {
                            randomAccessFile.close();
                            randomAccessFile = null;
                            return Integer.parseInt(item);
                        }
                    }
                }
            }
        } catch (Exception e) {
//            Log.w(TAG, e);
        } finally {
            if(randomAccessFile != null){
                try {
                    randomAccessFile.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                randomAccessFile = null;
            }
        }
        return 0;
    }

3.查看当前已经打开的文件数量:通过 /proc/(进程号)/fd 查看,也可以通过以下函数查看。如果数量随程序运行异常增加,则需要进一步排查由哪个模块导致的。

 public static int getFdCount() {
        File fdFile = new File("/proc/" + android.os.Process.myPid() + "/fd");
        File[] files = fdFile.listFiles();
        return null == files ? 0 : files.length;
    }

4.如果是socket忘记关闭,会打印出这种日志

0 lrwx------ 1 system system 64 2020-07-13 15:06 87 -> socket:[251044]

 socket后面的数字可以通过 cat /proc/net/tcp 或cat /proc/net/udp 或cat /proc/进程号/net/tcp或cat /proc/进程号/net/udp找到 。找到后是数据类似这样,其中7258B276:1F9A为远程ip地址和端口:118.178.88.114:8090

 434: 6600A8C0:8148 7258B276:1F9A 08 00000000:00000001 00:00000000 00000000  1000        0 58044 1 0000000000000000 28 3 30 10 -1       

5.根据以上内容,可以大致定位到什么没关闭导致的该问题,进一步分析自己写的代码排查即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值