AWS EC2 Linux下ProcessBuilder启动程序报Too many open file,其ulimit是多少?
核心结论
ProcessBuilder启动的子进程会继承其父进程(即运行这段Java代码的进程)的ulimit配置,和你交互式bash终端的ulimit配置没有关系。
配置不一致的原因
- 你在交互式bash终端查到的65535,是登录时通过PAM模块、用户profile配置(
/etc/profile、~/.bashrc等)加载生效的,仅对当前登录shell及其派生的子进程生效。 - 运行Java程序的父进程如果是systemd服务、开机自启脚本、非登录shell启动的进程,默认不会加载上述交互式shell的配置,全局默认的最大打开文件数限制通常为1024,远低于程序需要的5000,因此触发报错。
验证子进程实际生效的ulimit值
你可以修改代码通过ProcessBuilder直接执行ulimit -n,输出的结果就是子进程实际的文件打开数限制:
String cmd = "ulimit -n"; Process process = new ProcessBuilder() .inheritIO() .command("bash", "-c", cmd) .start();
修复方案
- 若Java程序由systemd管理:在对应service配置文件的
[Service]段落添加LimitNOFILE=65535,执行systemctl daemon-reload后重启Java服务即可生效。 - 若Java程序由脚本启动:在启动Java的脚本开头添加
ulimit -n 65535,再执行Java启动命令,后续ProcessBuilder拉起的子进程会继承该限制。 - 临时测试场景:在启动Java程序的终端先执行
ulimit -n 65535,再启动Java程序即可。
内容的提问来源于stack exchange,提问作者ca9163d9
相关产品推荐
相关产品推荐

