news 2026/4/16 13:49:54

OOM及资源监控管理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OOM及资源监控管理

背景:

日常的业务应用中,可能因为应用本身的可靠性问题导致内存泄漏,把机器搞挂,影响服务器中其他业务运行。这篇文档主要是简单介绍下 Linux 内核OOM killer功能,以及我们可以通过sytemd来限制服务的资源使用,避免服务一直去占用内存,导致服务器内存被耗尽。

关于OOM killer

OOM Killer 是 linux 内核在系统内存严重不足时使用的进程。出现这种情况是因为 linux 内核为其进程分配了过多的内存。

当一个进程启动时,它会向内核请求一块内存。这个初始请求通常是一个很大的请求,进程不会立即或实际上永远不会使用所有请求。内核意识到进程请求冗余内存的这种趋势,会过度分配系统内存。这意味着当系统具有例如 2GB 的 RAM 时,内核可能会为进程分配 2.5GB。

通常,这种情况不会导致问题。但是,如果有足够多的进程开始使用它们请求的所有内存块,那么将没有足够的物理内存来支持它们。这意味着正在运行的进程需要比物理可用更多的内存。这种情况很严重,必须立即解决。

linux内核采用的解决方案是调用OOM Killer来检查所有正在运行的进程并杀死其中一个或多个,以释放系统内存并保持系统运行

内核选择要杀死的进程的原则: 找到在短时间内占用大量内存的 进程,这些进程一般都是导致内存泄漏的罪魁祸首。

badness_for_task = total_vm_for_task / (sqrt(cpu_time_in_seconds) * sqrt(sqrt(cpu_time_in_minutes)))

可以通过 cat /proc/$PID/oom_score 来查看进程的 score

Out of memory: Kill process 1245 (test4) score 930 or sacrifice child

系统上关于OOM相关的一些sysctl配置:

vm.panic_on_oom

oom时重启系统,0 为不重启,1 为重启。部分情况下机器上只跑了一个关键服务,希望oom后重启机器来恢复业务可以设置为重启。 默认为0

vm.panic_on_oom=1
vm.oom_dump_tasks

允许内核在oom的时候转储进程信息,pid,vm大小,score分数,进程名称等,默认是允许的。 如果系统上有非常多的进程,这里打开可能会有系统性能损耗。默认为1 。 https://sysctl-explorer.net/vm/oom_dump_tasks/

vm.oom_dump_tasks=1
vm.oom_kill_allocating_task

如果将其设置为零,OOM killer 将扫描整个任务列表并根据打分选择要杀死的任务。这通常会选择一个流氓内存占用任务,该任务在被杀死时会释放大量内存。如果将其设置为非零,OOM 杀手只会杀死触发内存不足情况的任务。 默认是0 。 https://sysctl-explorer.net/vm/oom_kill_allocating_task/

vm.oom_kill_allocating_task=0
vm.overcommit_memory

https://sysctl-explorer.net/vm/overcommit_memory/

vm.overcommit_memory = 0

当此标志为 0 时,内核尝试估计用户空间请求更多内存时剩余的空闲内存量。

当这个标志为 1 时,内核假装总是有足够的内存,直到它实际用完。

当此标志为 2 时,内核使用“从不过度使用”策略来尝试防止任何内存过度使用

默认是0

资源监控

vmstat

sar

systemd/cgroup 资源监控管理

systemd-cgls 指令,根据 cgroup 将运行的进程分组来同时实现两者。 要显示您系统中的全部 cgroup 层级
systemd-cgls

查看 memory 资源管控器的 cgroup 树
systemd-cgls memory
systemd-cgls cpu
systemd-cgls devices

要查看按资源使用量(CPU、内存和 IO)排序的、正在运行的 cgroup 动态描述请使用: systemd-cgtop

slice: 控制组单元配置

以 ".slice" 为后缀的单元文件,用于封装管理一组进程资源占用的控制组的 slice 单元。slice 单元用于包含其他管理进程的单元(一般是 scope 与 service 单元)。 对 slice 单元施加的资源限制,将会作用于此 slice 单元所包含的全部进程的集合。 全部的 slice 单元按照树形层次结构组成一棵资源控制树。 slice 单元的名称由一系列"-"连接的字符串组成,对应着该单元在资源控制树层次结构中的位置。 根 slice 单元的名称固定为 -.slice 。例如, foo-bar.slice 是位于 foo.slice 之下的单元, 而 foo.slice 则位于根 -.slice 之下。

默认情况下,所有 service 与 scope 单元都位于 system.slice 之中

所有由 systemd-logind.service处理的用户会话都位于 user.slice 之中。

使用systemd-run临时创建cgroup

systemd-run可用于创建和启动瞬态的service/timer/scope。并在其中运行指定的命令。

systemd-run --unit=test --scope --slice=jkksl sleep 20

systemd-run --unit=test --slice=jkksl --remain-after-exit sleep 20

systemd-run --unit=test --remain-after-exit sleep 20 [常用]

systemd-run sleep 20

--unit 指定unit 名称,不加的话会自动生成一个

[root@TEST system-generators]# systemd-run sleep 789 Running as unit run-9864.service. [root@JKK-ASSIST-TEST system-generators]# systemctl status run-9864 ● run-9864.service - /usr/bin/sleep 789 Loaded: loaded (/run/systemd/system/run-9864.service; static; vendor preset: disabled) Drop-In: /run/systemd/system/run-9864.service.d └─50-Description.conf, 50-ExecStart.conf Active: active (running) since 日 2022-02-27 17:03:34 CST; 9s ago Main PID: 9865 (sleep) CGroup: /system.slice/run-9864.service └─9865 /usr/bin/sleep 789 2月 27 17:03:34 TEST systemd[1]: Started /usr/bin/sleep 789.

--scope 创造一个过渡期。范围单位,而不是默认的瞬态。服务单位 ,不指定的默认是在system.slice 下。

--slice 创建一个新的.service或者.scope unit来替代system.slice

临时 cgroup 所包含的进程一旦结束,临时 cgroup 就会被自动释放。通过将 --remain-after-exit 选项传递给 systemd-run,您可以在其进程结束后,让单位继续运行来收集运行时的信息

永久的创建cgroup: 创建修改.service

systemd-cgls 命令默认显示整体cgroup层级,cgroup 树的最高层由 slice 构成

systemd-cgls 后面可以加上参数显示cgroup层级特定部分

systemd-cgls cpu systemd-cgls memory systemd-cgls devices

查看特定进程的cgroup信息

cat proc/PID/cgroup

监控资源消耗量

systemd-cgtop

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #define KB (1024) #define MB (1024 * KB) #define GB (1024 * MB) int main() { while(1) { void *m = malloc(KB); memset(m,0,KB); sleep(0.1); } return 0; }
[Unit] Description=cgroup demo test Before=shutdown.target Conflicts=shutdown.target [Service] ExecStart=/root/test RemainAfterExit=yes MemoryLimit=800M TimeoutSec=0

应用内存达到限制后,会被systemd kill

systemd[1]: cgtest.service: Main process exited, code=killed, status=9/KILL

资料链接

《ook-killer》

https://www.kernel.org/doc/gorman/html/understand/understand016.html

https://www.oracle.com/technical-resources/articles/it-infrastructure/dev-oom-killer.html

《redhat 7资源管理指南》

https://access.redhat.com/documentation/zh-cn/red_hat_enterprise_linux/7/html/resource_management_guide/index

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/15 13:43:57

【计算机毕业设计案例】基于微信小程序的快递代收发的设计与实现基于springboot+微信小程序的快递代取系统的设计与实小程序(程序+文档+讲解+定制)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/4/16 11:01:05

【计算机毕业设计案例】基于springboot+微信小程序的集换社卡牌的交易系统小程序基于微信小程序的集换式卡牌交易系统(程序+文档+讲解+定制)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/4/16 11:02:05

【紧急升级】金融客服Agent必须具备的情绪识别能力,错过将被淘汰

第一章&#xff1a;金融客服Agent情绪识别的紧迫性与战略价值在数字化金融服务迅速普及的背景下&#xff0c;客户与金融机构之间的交互 increasingly 依赖于智能客服系统。然而&#xff0c;传统客服Agent往往缺乏对用户情绪的敏感度&#xff0c;导致服务体验机械化、响应迟缓&a…

作者头像 李华
网站建设 2026/4/16 12:28:53

影刀RPA一键处理Zozone达人合作订单,效率飙升1000%![特殊字符]

影刀RPA一键处理Zozone达人合作订单&#xff0c;效率飙升1000%&#xff01;&#x1f680;还在手动处理达人订单&#xff1f;每天重复核对信息、确认佣金、更新状态&#xff0c;耗时耗力还容易算错钱&#xff1f;今天带你用影刀RPA打造达人订单智能处理机器人&#xff0c;1000个…

作者头像 李华
网站建设 2026/4/16 12:31:27

数据结构与算法基础:时间复杂度、存储结构与链表操作详解

数据结构与算法基础&#xff1a;时间复杂度、存储结构与链表操作详解 在学习数据结构与算法的过程中&#xff0c;理解基本概念是构建扎实编程能力的关键。本文将围绕以下四个核心知识点展开讲解&#xff1a; 算法的时间复杂性与问题规模的关系顺序存储结构的定义与特点数据结构…

作者头像 李华
网站建设 2026/4/15 10:43:23

118. 杨辉三角

已解答 简单 相关标签 premium lock icon 相关企业 给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 示例 1: 输入: numRows 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] 示…

作者头像 李华