0

0

Linux内存限制方案_cgroup内存控制解析【指导】

冰川箭仙

冰川箭仙

发布时间:2026-01-02 18:05:37

|

388人浏览过

|

来源于php中文网

原创

cgroup v1 的 memory.limit_in_bytes 不生效的根本原因是容器或进程未真正运行在指定 cgroup 下,或内核未启用 memory 子系统;需检查挂载、进程归属、路径创建及 systemd/cgroup 版本兼容性。

linux内存限制方案_cgroup内存控制解析【指导】

为什么 cgroup v1memory.limit_in_bytes 有时不生效

根本原因常是容器或进程没真正运行在指定 cgroup 路径下,或者内核未启用对应控制组子系统。检查时先确认 /sys/fs/cgroup/memory 是否可挂载且非空;再看目标进程的 cgroup.procs 文件是否包含其 PID。

  • cat /proc//cgroup 确认进程归属的 memory cgroup 路径
  • 写入限制前必须确保该 cgroup 目录已创建,且 memory.limit_in_bytes 文件存在(不是只读)
  • 若使用 systemd 启动服务,需通过 MemoryLimit= 设置,而非手动操作 /sys/fs/cgroup 下文件——systemd 会接管并覆盖手动配置
  • 某些发行版(如 RHEL 8+/CentOS 8+)默认启用 cgroup v2,此时 memory.limit_in_bytes 不可用,应改用 memory.max

cgroup v2 中设置内存上限:用 memory.max 而非 memory.limit_in_bytes

cgroup v2 统一了接口,所有资源控制都通过单一层级实现。内存限制字段变为 memory.max,单位仍是字节,但支持特殊值:max 表示无限制,0 表示禁止分配新内存(等效于立即 OOM)。

  • 创建 v2 cgroup:先挂载 mount -t cgroup2 none /sys/fs/cgroup,然后 mkdir /sys/fs/cgroup/myapp
  • 设上限为 512MB:
    echo 536870912 > /sys/fs/cgroup/myapp/memory.max
  • 将进程加入:
    echo  > /sys/fs/cgroup/myapp/cgroup.procs
  • 注意:v2 下 memory.usage_in_bytes 已改为 memory.current,监控时别用错路径

OOM 发生时为何进程没被杀,而是卡住或响应迟缓

这是因 memory.oom_control(v1)或 memory.oom(v2)默认开启“OOM killer”,但实际触发取决于当前内存压力与页面回收效率。若进程持续申请不可回收内存(如匿名 mmap + 锁页),或 cgroup 内有多个子组竞争,OOM killer 可能延迟响应甚至无法及时选中目标进程。

魔术橡皮擦
魔术橡皮擦

智能擦除、填补背景内容

下载
  • v1 中可关闭自动 kill:echo 1 > memory.oom_control,此时超限时直接阻塞内存分配(malloc 返回 NULL,mmap 失败)
  • v2 中等效机制是写 memory.oom0,但更推荐配合 memory.high 做软性限流——它会在接近阈值时主动回收内存,避免突兀 OOM
  • 检查是否真触发 OOM:dmesg -T | grep -i "killed process",若无输出,说明只是内存紧张而非被杀

和 Docker/Kubernetes 的内存限制冲突怎么办

Docker 默认使用 cgroup v2(1.21+),Kubernetes 则依赖 kubelet 配置的 cgroupDriver。若宿主机手动修改了某 cgroup 路径下的限制,而容器运行时又覆盖了同一路径,结果不可预测——通常以最后写入者为准,但可能引发状态不一致。

  • 不要在 Docker 容器运行后手动改其 cgroup 目录(如 /sys/fs/cgroup/mycontainer/...),Docker 会定期同步配置
  • Kubernetes 中应统一通过 Pod 的 resources.limits.memory 控制,底层由 kubelet 转为 memory.maxmemory.limit_in_bytes
  • 调试时可查容器真实 cgroup 路径:cat /proc//cgroup,再比对 memory.max 值是否匹配预期

最易被忽略的是 cgroup 版本混用:同一个系统里 v1 和 v2 可能共存,但不能对同一进程同时生效。确认清楚当前环境用的是哪套接口,再选对应字段操作,否则所有设置都是徒劳。

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

229

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

434

2024.03.01

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

994

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

53

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

239

2025.12.29

k8s和docker区别
k8s和docker区别

k8s和docker区别有抽象层次不同、管理范围不同、功能不同、应用程序生命周期管理不同、缩放能力不同、高可用性等等区别。本专题为大家提供k8s和docker区别相关的各种文章、以及下载和课程。

249

2023.07.24

docker进入容器的方法有哪些
docker进入容器的方法有哪些

docker进入容器的方法:1. Docker exec;2. Docker attach;3. Docker run --interactive --tty;4. Docker ps -a;5. 使用 Docker Compose。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

492

2024.04.08

docker容器无法访问外部网络怎么办
docker容器无法访问外部网络怎么办

docker 容器无法访问外部网络的原因和解决方法:配置 nat 端口映射以将容器端口映射到主机端口。根据主机兼容性选择正确的网络驱动(如 host 或 overlay)。允许容器端口通过主机的防火墙。配置容器的正确 dns 服务器。选择正确的容器网络模式。排除主机网络问题,如防火墙或连接问题。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

396

2024.04.08

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

143

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 6.4万人学习

Git 教程
Git 教程

共21课时 | 2.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号