Files.list 未使用 try-with-resources 处理导致触发 Linux 系统 Open Files 上限, 进而导致 Java 程序报 打开的文件过多

博文目录

文章目录


结论

当使用 Files 工具包时, 需要额外注意返回值类型, 如果是 Stream 以及 DirectoryStream 这两个接口, 则需要在使用后及时调用其 close 方法释放资源, 推荐使用更优雅的 try-with-resources 结构

如果不执行 close 释放资源, 则打开的文件等资源将一直被占用, 直到 Java 进程终止. 当打开的资源足够多, 就有可能触发到 Linux 系统配置的进程打开文件上限, 进而导致 Java 进程功能异常, 报错 打开的文件过多

过程

首先是上传文件发现系统异常, 查日志发现是报 打开的文件过多, 通过 lsof -p 47090 | wc -l 发现 Java 进程打开了 4000+ 文件, 通过 ulimit -aulimit -n 查看系统配置的 Open Files 上限是 1024, 通过 lsof -p 47090 查看打开的文件列表, 发现里面有很多是上传文件的文件夹目录, 类似下面

...
java    47090 root  472r      DIR              253,2        47 15032447518 /home/bid/upload/53b9bbe6e29e7eadeffa7c03962108c5
java    47090 root  473r      DIR              253,2        47 15032447518 /home/bid/upload/53b9bbe6e29e7eadeffa7c03962108c5
java    47090 root  474r      DIR              253,2        50 16643000312 /home/bid/upload/799e6138b45ac922d9c34a218a47c3a8
java    47090 root  475r      DIR              253,2        47  1077111019 /home/bid/upload/c942c119927d83a3d9bb4e13a46adc75
java    47090 root  477r      DIR              253,2        53        7160 /home/bid/upload/66a37cd0d1f4c76c9aaafcfbb82203d9
java    47090 root  478r      DIR              253,2        47  1077111019 /home/bid/upload/c942c119927d83a3d9bb4e13a46adc75
java    47090 root  481r      DIR              253,2        53  1611530376 /home/bid/upload/41a9b0ca26a194bf204ccf83ee199c67
java    47090 root  482r      DIR              253,2        50  5368709550 /home/bid/upload/8ec135c1594ef233337b2a041a558c20
java    47090 root  485r      DIR              253,2        50  5368709550 /home/bid/upload/8ec135c1594ef233337b2a041a558c20
...

重启 Java 进程后, 查看打开的文件数是 350 左右, 可正常上传文件, 但是随着上传文件接口的调用, 打开的文件数在不停上涨, 且对应的文件目录一直处于打开状态, 不能及时释放, 怀疑是流之类的没有及时关闭, 导致资源没有释放

检查代码, 发现没有使用到 InputStream / OutputStream 之类的 IO 流, 但是有使用到 Files.list 方法, 其返回值类型是 Stream<Path>, 同样需要 close, 在加了 try-with-resources 处理后, 重启 Java 进程, 发现打开的文件数不再上涨, 维持在 350 左右, 且打开的文件列表里的目录类型也会很快被释放, 问题解决

查看 Files 工具类, 发现其中有好几个方法会返回 Stream<Path>DirectoryStream<Path>, 比如 find / lines / list / newDirectoryStream / walk, 都需要做 try-with-resources 处理

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值