LimitDATA是systemd对服务进程数据段大小的硬性限制,影响堆内存、全局变量及动态模块加载;Nginx因共享内存或Lua模块易超默认64MB限制,需通过systemctl edit nginx设置LimitDATA=2G等值并重载生效。

Linux下Nginx通过systemd启动时,若遇到 Segmentation fault (core dumped) 或加载模块(如动态模块、Lua、OpenResty)失败,且日志中提示内存分配异常(如 mmap: Cannot allocate memory),很可能是 systemd 限制了进程的 LimitDATA(即数据段大小,对应 RLIMIT_DATA)。
什么是LimitDATA?
LimitDATA 是 systemd 对服务进程可使用的「数据段最大字节数」的硬性限制,影响堆内存(malloc)、全局/静态变量、动态链接模块等占用的虚拟内存空间。Nginx 默认使用大量共享内存(shared memory zones)、加载动态模块(如 ngx_http_lua_module)或启用大量 worker 进程时,容易突破默认限制(通常是 64MB 或无限但受内核策略约束)。
如何查看当前LimitDATA设置
运行以下命令检查 Nginx 服务的实际限制:
systemctl show nginx | grep LimitDATA # 或查看运行中主进程的资源限制 cat /proc/$(pgrep -f "nginx: master")/limits | grep "Max data size"
输出类似:
LimitDATA=67108864 (bytes) → 即 64MB
如何修改LimitDATA
在 systemd service 文件中覆盖限制(推荐方式):
- 编辑 Nginx 的 service 配置:
sudo systemctl edit nginx - 添加如下内容(例如设为 2GB):
[Service] LimitDATA=2147483648
- 重载配置并重启:
sudo systemctl daemon-reload && sudo systemctl restart nginx
⚠️ 注意:
– 数值单位是字节;可用后缀如 2G、512M(systemd 229+ 支持);
– 若设为 infinity,表示不限制(需确保内核和 ulimit 允许);
– 修改仅对 systemd 启动的 Nginx 生效,不适用于手动 ./nginx 运行。
配合其他相关限制检查
LimitDATA 不是孤立项,常需同步确认:
-
LimitAS(Address Space):虚拟内存总上限,应 ≥ LimitDATA; -
MemoryLimit(cgroup v2):若启用 Memory Controller,该值会覆盖传统 rlimit; - 内核参数
vm.max_map_count:影响 mmap 区域数量,动态模块多时建议调高(如262144); - Nginx 自身配置:避免过度设置
worker_rlimit_data(已废弃)或滥用lua_shared_dict大小。










