cgroup v1 限制 Java 进程内存硬上限需三步:挂载 memory 子系统、创建控制组并设 memory.limit_in_bytes 与 memory.memsw.limit_in_bytes、将进程所有线程完整加入该 cgroup,缺一不可。

直接用 cgroup v1 给 Java 进程设内存硬上限,关键不是“加限制”,而是确保限制真正生效、不被绕过、不被 swap 干扰。核心动作就三步:挂载 memory 子系统、创建控制组并写死上限、把整个 Java 进程(含所有线程)完整塞进去。
确认并挂载 memory cgroup 子系统
先检查是否已挂载:
mount | grep cgroup | grep memory
如果没输出,说明未挂载,执行:
sudo mkdir -p /sys/fs/cgroup/memory
sudo mount -t cgroup -o memory none /sys/fs/cgroup/memory
注意:必须带 memory 选项,不能只挂 cgroup 默认路径;部分发行版(如较新 Ubuntu/CentOS)可能已默认挂载,但路径可能是 /sys/fs/cgroup/memory 或 /cgroup/memory,请以 mount 命令输出为准。
创建控制组并设置硬内存上限
在 memory 挂载点下建一个专属目录,比如叫 java-prod:
sudo mkdir /sys/fs/cgroup/memory/java-prod
将后端 Java 接口文档转换为前端 TypeScript 类型定义(interface / type)。输入:飞书文档、Spring Boot 接口文档、Swagger/OpenAPI、手写 API 文档等。输出:包含请求参数与响应结果的 .md 文件,含完整 JSDoc 注释。触发关键词:Java 转 TS、接口转换、生成前端类型、接口文档转 TypeScript、DTO/VO/BO 转 interface、后端文档转前端类型、生成接口类型、类型定义生成。
写入硬限制值(单位字节)。例如限制为 1GB:
echo 1073741824 | sudo tee /sys/fs/cgroup/memory/java-prod/memory.limit_in_bytes
同时禁用 swap 干扰(否则内核会先用 swap,导致实际物理内存超限却不触发 OOM):
echo 1073741824 | sudo tee /sys/fs/cgroup/memory/java-prod/memory.memsw.limit_in_bytes
这一步必须做——memory.memsw.limit_in_bytes 必须 ≤ memory.limit_in_bytes,否则硬限失效。若系统本身禁用了 swap(swapoff -a),可跳过此行,但建议显式设置保持行为一致。
将 Java 进程完整纳入该 cgroup
Java 是多线程应用,所有线程共享进程内存空间,内核按进程粒度统计 RSS。必须确保主线程和所有子线程都在同一个 cgroup 中:
- 启动前加入:用
cgexec启动是最稳妥的方式
sudo cgexec -g memory:java-prod java -Xms512m -Xmx512m -jar app.jar - 运行中加入:若进程已在运行,获取其 PID(如
1234),写入tasks文件
echo 1234 | sudo tee /sys/fs/cgroup/memory/java-prod/tasks - 验证是否全部线程都进来了:
ls /proc/1234/task/ | while read tid; do cat /proc/1234/task/$tid/cgroup 2>/dev/null | grep java-prod; done | wc -l
输出数应等于该进程线程总数(ps -T -p 1234 | wc -l)
验证硬限是否真实起效
光写配置不等于生效。必须实测:
- 用
stress-ng压测(或让 Java 主动分配大量对象):
sudo stress-ng --vm 1 --vm-bytes 1.2G --timeout 20s
观察是否在接近 1GB 时被 OOM killer 杀掉(dmesg -T | tail -20查 “Killed process” 日志) - 实时看用量:
cat /sys/fs/cgroup/memory/java-prod/memory.usage_in_bytes
超过memory.limit_in_bytes时,该值会卡在上限附近,且memory.failcnt计数器会递增 - 检查是否因内核未启用 memory controller 导致无效:
cat /proc/cgroups | grep memory
第四列(enabled)必须为 1
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










