java应用linux部署需同时配置nproc和nofile软硬限制,覆盖root与所有用户,并启用pam_limits.so;systemd服务还需在service文件中显式设置limitnproc和limitnofile并重载生效。

Java 应用在 Linux 上部署时,常因系统资源限制报错,比如 java.lang.OutOfMemoryError: unable to create new native thread(线程创建失败)或 Too many open files(文件句柄耗尽)。这两个问题分别对应**最大进程/线程数(nproc)** 和 **最大打开文件数(nofile)**,仅靠改 /etc/security/limits.conf 不够——必须配全、配对、配准,否则 Java 进程根本读不到新值。
明确要改的两个核心项
nproc:限制单个用户所有进程 + 线程总数(Java 的每个线程都占一个 PID);
nofile:限制单个进程可打开的文件描述符总数(包括 socket、jar 包、日志、配置等)。
二者都需同时设置 soft(当前生效值)和 hard(上限,soft 不能超 hard),且 hard 值必须 ≥ soft。
正确写法:覆盖 root 和普通用户
/etc/security/limits.conf 中的 * 不匹配 root,也不影响 systemd 启动的服务。Java 应用若以 root 或专用用户(如 appuser)运行,必须显式声明:
root soft nproc 65535root hard nproc 65535root soft nofile 65535root hard nofile 65535* soft nproc 65535* hard nproc 65535* soft nofile 65535* hard nofile 65535
建议统一设为 65535(或 unlimited,仅限 root),避免 soft/hard 冲突导致整行被 PAM 忽略。
必须启用 PAM 加载模块
limits.conf 是 PAM 模块 pam_limits.so 的配置文件,不加载就完全无效。检查并确保以下文件含该行:
- Ubuntu/Debian:
/etc/pam.d/common-session和/etc/pam.d/common-session-noninteractive - RHEL/CentOS:
/etc/pam.d/system-auth或/etc/pam.d/login
内容必须是:session required pam_limits.so(注意不是 optional 或路径错误)。
Java 进程是否真能读到?关键看启动方式
如果 Java 应用通过 systemctl start myapp 启动(绝大多数生产部署方式),它完全不读 limits.conf——因为 systemd 绕过 PAM 登录流程。
此时必须额外配置 service 文件:
- 编辑
/etc/systemd/system/myapp.service - 在
[Service]段添加:LimitNPROC=65535 LimitNOFILE=65535
- 执行:
sudo systemctl daemon-reload && sudo systemctl restart myapp
验证是否生效:prlimit -n $(pidof java) 查 nproc,prlimit -n $(pidof java) 查 nofile(注意不是 ulimit -n,那是查当前 shell)。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











