javaspring-boot

"Too many open files" after 1 month runtime


I have a Spring Boot app that checks for files every 10s.

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

After about 1 month of permanent runtime, I see an exception:

too many open files

It disappears as soon as I restart the app. Not sure if it is at the Files.list or bar.

But I do not have any reading/writing of files without closing. So I have no clue why this happens.

Any ideas? How can I prevent/monitor this?


Solution

  • Those are file descriptors, leaked because the Stream isn't closing properly(Files.list).

    The Files.list(Path) method returns a Stream<Path>.

    This stream must be closed with a try-with-resources, not just a try-catch.

    try (Stream<Path> stream = Files.list(Path.of("mydir"))) {
        List<Path> ps = stream.sorted().collect(Collectors.toList());
        for (Path p : ps) 
            bar(p);        
    } catch (Exception e) {
        System.out.println(e.getMessage());
    }
    

    https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

    The try-with-resources statement is a try statement that declares one or more resources. A resource is an object that must be closed after the program is finished with it. The try-with-resources statement ensures that each resource is closed at the end of the statement. Any object that implements java.lang.AutoCloseable, which includes all objects which implement java.io.Closeable, can be used as a resource.