systemd 的 LimitAS 限制虚拟地址空间,Nginx 因加载 SSL、缓存等易触发 fork: Cannot allocate memory;应设为 infinity 或合理值(如 4G),并配合 MemoryMax 控制物理内存。

当使用 systemd 管理 Nginx 时,如果 Nginx 启动失败并报错类似 fork: Cannot allocate memory 或日志中出现 Out of memory: Kill process … (nginx),同时 systemctl status nginx 显示进程被 OOM killer 终止,很可能是 systemd 对该服务设置了过严的 LimitAS(即地址空间限制),导致 Nginx 在加载大量配置、SSL 证书、模块或处理高并发连接时因虚拟内存不足而失败。
什么是 LimitASSIZE(LimitAS)
LimitAS 是 systemd 的资源限制参数,对应 Linux 的 RLIMIT_AS,它限制进程及其所有子进程可使用的**最大虚拟地址空间字节数**(包括代码、数据、堆、栈、mmap 映射等)。单位是字节,值为 infinity 表示不限制。Nginx 尤其在启用大量 ssl_certificate、proxy_cache_path、large_client_header_buffers 或第三方模块(如 ModSecurity)时,会申请大量虚拟内存(即使物理内存充足),容易触达 LimitAS 上限。
检查当前 LimitAS 设置
运行以下命令查看 Nginx 服务实际生效的 LimitAS 值:
查看服务单元的配置来源:
-
systemctl show nginx.service | grep LimitAS—— 显示当前生效值(可能来自默认、drop-in 或主配置) -
systemctl cat nginx.service—— 查看原始 unit 文件 -
ls /etc/systemd/system/nginx.service.d/—— 检查是否有自定义 drop-in(如override.conf)覆盖了限制
注意:若输出为 LimitAS=67108864,即 64MB,这对现代 Nginx 来说严重不足;常见安全加固模板可能误设此值。
安全地解除或放宽 LimitAS 限制
不建议直接删掉限制,而是显式设为合理值或取消硬性约束:
- 创建或编辑 drop-in 配置:
sudo systemctl edit nginx.service - 在打开的编辑器中输入:
[Service] LimitAS=infinity # 或设为较大值(如 4GB):LimitAS=4294967296
- 保存退出后重载配置:
sudo systemctl daemon-reload - 重启服务:
sudo systemctl restart nginx - 验证生效:
systemctl show nginx.service | grep LimitAS应显示infinity或你设定的数值
⚠️ 注意:设为 infinity 不代表无管控,只是不限制虚拟地址空间;OOM 风险仍由系统整体内存和 MemoryMax(若启用 cgroup v2 内存控制器)兜底。
其他关联限制也需留意
LimitAS 常与以下参数一同被误配,排查时一并检查:
-
LimitDATA:限制数据段大小(影响 malloc 分配),Nginx 动态配置加载可能受其影响 -
MemoryMax(cgroup v2):若启用了统一 cgroup,该值会硬性限制总物理内存使用,优先级高于LimitAS -
TasksMax:限制最大线程/进程数,高并发下可能触发fork: retry: Resource temporarily unavailable
推荐做法:仅对明确需要沙箱隔离的服务设置严格资源限制;对 Nginx 这类核心反向代理,保持 LimitAS=infinity + 合理 MemoryMax(如 MemoryMax=2G)更平衡可靠。


















