You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

运行1个月后Spring Boot应用出现Too many open files异常求助

排查思路

1. 优先排查Files.list的资源泄漏问题

Files.list(Path)返回的Stream<Path>关联了底层的目录文件描述符,必须显式关闭。你的代码中直接调用collect(Collectors.toList())后,Stream未被关闭,即使遍历完成,部分JDK实现仍可能保留底层资源不释放。每10秒泄漏1个文件描述符,1个月累计泄漏约43200个,很容易触发系统的文件描述符上限。

2. 排查bar()方法的资源泄漏

即使你认为没有未关闭的文件操作,也可能存在遗漏:

  • 检查bar()中所有文件读写相关代码,是否有未关闭的InputStream/OutputStream、Reader/Writer、FileChannel等资源。
  • 确认异常分支下资源是否被正确关闭(比如未用try-with-resources或finally块)。

3. 用工具定位泄漏点

  • 系统层面:Linux下执行lsof -p <你的应用PID>查看进程打开的所有文件,或ls /proc/<PID>/fd | wc -l统计当前打开的文件描述符数量,观察是否随时间持续增长。
  • Java层面:
    • 用jmap -dump:format=b,file=heap.hprof <PID>导出堆快照,用MAT(Memory Analyzer Tool)分析未被回收的流、文件资源对象,定位泄漏源头。
    • 用jstack <PID>查看线程栈,是否有阻塞的文件操作导致资源无法释放。
    • 启用Java Mission Control的飞行记录器,追踪文件描述符的分配与释放流程,精准定位泄漏点。
预防措施

1. 正确关闭Files.list的Stream

使用try-with-resources语法保证Stream自动关闭,即使发生异常:

@Scheduled(fixedRateString = "10000")
public void foo() {   
    try (Stream<Path> dirStream = Files.list(Path.of("mydir"))) {
        List<Path> ps = dirStream.sorted().collect(Collectors.toList());       
        for (Path p : ps) {
           bar(p); 
        }
    } catch (Exception e) {
        System.out.println(e.getMessage());
    }
}

2. 规范所有文件资源操作

所有实现AutoCloseable的资源(流、通道等)都必须用try-with-resources包裹,确保自动关闭。比如bar()方法中的文件操作:

private void bar(Path p) throws IOException {
    try (InputStream in = Files.newInputStream(p)) {
        // 业务处理逻辑
    }
}

3. 优化定时任务逻辑

如果目录文件变更不频繁,改用WatchService监听目录变化,替代定时轮询,减少不必要的资源占用。

4. 调整系统文件描述符上限(应急缓解)

Linux下修改/etc/security/limits.conf,提升进程可打开的文件描述符数量:

* soft nofile 65535
* hard nofile 65535

修改后需重启系统或重新登录用户生效,这只是临时缓解,核心解决手段还是修复资源泄漏。

监控方法

1. 系统层面监控

  • 编写定时脚本,定期执行ls /proc/<PID>/fd | wc -l,将结果写入日志或监控系统,当数值接近阈值(比如最大值的80%)时触发报警。
  • 用Prometheus + Grafana配合node_exporter,收集进程的文件描述符使用指标,设置告警规则。

2. Java应用层面监控

  • 启用Spring Boot Actuator,通过jvm.file.descriptors指标监控文件描述符的已使用数、最大值等,结合Prometheus采集数据并告警。
  • 自定义监控逻辑:通过ManagementFactory.getOperatingSystemMXBean()获取系统MXBean,实时获取文件描述符使用情况,上报到内部监控平台。
  • 定期用Java Mission Control录制飞行记录,分析资源使用趋势,提前发现泄漏迹象。

内容的提问来源于stack exchange,提问作者chris01

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 06:08:15