复现

  1. 当执行一段 Shell 指令时出现
Failed to allocate directory watch: Too many open files
  1. 执行 Java 程序时出现
[19:20:04] [main/WARN]: Failed to create config file watcher 
 java.io.IOException: User limit of inotify instances reached or too many open files 
         at java.base/sun.nio.fs.LinuxWatchService.<init>(LinuxWatchService.java:62) \~[?:?] 
         at java.base/sun.nio.fs.LinuxFileSystem.newWatchService(LinuxFileSystem.java:53) \~[?:?] 
         at org.spongepowered.asm.mixin.transformer.MixinTransform
  • 以上问题的原因是(​无法分配目录监视:打开的文件过多​)并不是指你打开的普通文件数量过多,而是特指你的系统已经达到了 inotify 监视器的数量限制。

解决方案

增加 Inotify 监视器限制

你需要修改内核参数来永久性地增加 Inotify 监视器限制。

  1. 创建或编辑配置文件:
    打开或创建一个新的 sysctl 配置文件,用于存放这些设置。通常,我们会在 /etc/sysctl.d/ 目录下创建一个新文件,例如 99-inotify.conf。这样做的好处是它不会覆盖系统的主要 sysctl.conf 文件,并且你的更改会持久化。
    打开终端,输入以下命令:

    sudo nano /etc/sysctl.d/99-inotify.conf
    

    (如果你不熟悉 nano 编辑器,也可以用 geditvi 等其他编辑器。)

  2. 添加或修改参数:
    在打开的文件中,添加或修改以下两行:

    fs.inotify.max_user_watches = 524288
    fs.inotify.max_user_instances = 1024
    
    • fs.inotify.max_user_watches: 这是单个用户可以监视的最大文件/目录数量。524288 (512K) 通常是一个足够大的值。
    • fs.inotify.max_user_instances: 这是单个用户可以创建的 Inotify 实例的最大数量。1024 通常也足够。

    保存文件并退出编辑器(如果你用 nano:按 Ctrl + O 保存,按 Enter 确认文件名,然后按 Ctrl + X 退出)。

  3. 应用更改:
    为了让这些新的设置立即生效而无需重启电脑,请在终端中运行以下命令:

    sudo sysctl --system
    
  4. 验证更改(可选但推荐):
    你可以运行以下命令来确认新的限制是否已经生效:

    sysctl fs.inotify
    

    输出应该会显示你刚才设置的 max_user_watchesmax_user_instances 的新值。

  5. 重启相关应用程序:
    最后,重启之前遇到这个错误的应用程序(例如,你的 IDE、文件同步工具等),它们就会应用新的 Inotify 限制,错误应该就会消失了。


完成以上步骤后,你应该就不会再遇到“Failed to allocate directory watch: Too many open files”的错误了。