惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

GbyAI
GbyAI
爱范儿
爱范儿
Y
Y Combinator Blog
T
Tor Project blog
V
Visual Studio Blog
U
Unit 42
B
Blog RSS Feed
博客园 - 叶小钗
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
阮一峰的网络日志
阮一峰的网络日志
T
Tailwind CSS Blog
G
Google Developers Blog
I
InfoQ
Stack Overflow Blog
Stack Overflow Blog
IT之家
IT之家
Microsoft Azure Blog
Microsoft Azure Blog
T
The Blog of Author Tim Ferriss
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
The Cloudflare Blog
Google DeepMind News
Google DeepMind News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
H
Hackread – Cybersecurity News, Data Breaches, AI and More
F
Fortinet All Blogs
人人都是产品经理
人人都是产品经理
Apple Machine Learning Research
Apple Machine Learning Research
The GitHub Blog
The GitHub Blog
Recorded Future
Recorded Future
博客园_首页
罗磊的独立博客
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
量子位
P
Proofpoint News Feed
Jina AI
Jina AI
博客园 - 【当耐特】
S
Security @ Cisco Blogs
I
Intezer
MyScale Blog
MyScale Blog
Simon Willison's Weblog
Simon Willison's Weblog
P
Privacy & Cybersecurity Law Blog
腾讯CDC
T
Tenable Blog
A
Arctic Wolf
T
Threat Research - Cisco Blogs
S
Securelist
Know Your Adversary
Know Your Adversary
Spread Privacy
Spread Privacy
C
Check Point Blog
NISL@THU
NISL@THU
Microsoft Security Blog
Microsoft Security Blog
V
Vulnerabilities – Threatpost

Oskyla 烹茶室

修复 Joplin on KDE 菜单栏显示问题 Copy Fail:Linux 内核 2017 年至今的高危漏洞(附临时缓解方案) | CVE-2026-31431 Hermes Agent — 在 K3s / K8s 中运行指南 在 K3s 节点上安装并使用 nerdctl Mouser:轻量开源的罗技鼠标驱动替代方案 Claude Opus 4.7:优缺点与评测信息汇总 openFuyao NPU-Operator故障排查 openFuyao 2603 共测测试报告 openFuyao InferNex AI推理集成部署 310P(300I Pro) 环境问题记录及解决 ceph mon Operation not permitted 问题解决 Ascend 310P + openFuyao + NPU-Operator 故障排查 KDE Plasma6 禁用全局菜单,恢复正常应用菜单 终极指南:在 Linux 裸机服务器上快速部署 Moltbot (原 Clawbot) 并集成飞书 Windows 配置 Claude Code 解决 settings.json 不生效 Windows 配置 Claude Code 全流程 2025-12-31 | 年终总结 AI 生图精品提示词|第二期:城市星球 AI 生图精品提示词|第一期 Kubernetes kubectl --raw 使用指南 彻底解决阿里云和 tailscale 冲突 2025-10-21 | 沉淀思维 macOS 单独为鼠标或触控板开启自然滚动 2025-10-16 | 负载高低 2025-10-15 | 睡眠周期 2025-10-14 | 转换情绪与独立观点 go 拉取 gitcode.com 私有 mod Git 将某个文件恢复到其他分支的状态 SSH 通过跳板机连接 lxc 使用 chronyc 构建 ntp 服务 2025-10-13 | 独立思考于未来能源 2025-10-12|AI Review 及高质量工作流 2025-10-11 | 人生阶段 2025-10-10 | AI Logo | 远程操控 AI 2025-10-09 | 去班味|银杏|域名 2025-10-08 2025-10-07 2025-10-06 2025-10-05 优秀的 SubReddit 清单 Synology 群晖重置 Syncthing 密码 让 LLM 看到真实世界的 Playwright MCP 磁盘占用分析利器 ncdu 自建 gitlab 徽标问题导致项目 500 问题解决 harbor Chartmuseum helm 图表缓存刷新 grep exclude 排除 Debian 11 + PVE LACP Mac 冲突问题调查与解决方案 Claude Code 实用技巧 CentOS 7 重置 root 密码 telnet 如何退出 kubernetes 的挂载传播(mount propagation)机制 vim 将命令输出到当前位置 harbor 替换 ssl 证书 AI提效之使用 cherry-studio + k8sgpt 实现 AI 巡检 k8s Claude Code Subagents 快速开始 《我看见的世界:李飞飞自传》 Lyra - AI Prompt Optimization Specialist Linux 自签名 CA 证书安装方法 超级玛丽、魂斗罗等经典小游戏聚合站 | PlayUnb 个人业余开发项目清单 快速选出收益最高的理财产品 | finance-calculator 苹果液态玻璃风格图像生成和模拟器 | LiquedGlass.icu Linux 进程绑定NUMA节点或CPU核心 判断GPT是否降智的几个问题 Harmony next hap 安装 名侦探柯南贝尔摩德出场集数 k3s k8s 快速部署轻量节点监控方案 beszel k3s-k8s 实现 DevOps 方案横向对比 k8s 配置访问私有镜像仓库 GoAccess 分析多网站日志方法 Octant - 以开发人员为中心的开源 Kubernetes Web 界面 Tailscale 自建 DERP 并配置 SSL 完整教程 OpenManus 使用记录 Plausible 缺失 location 信息的研究 解决 Nginx Ingress returns 413 Entity Too Large 绘图模型效果对比之城市气象 【转】k8s 认知路线 OpenFOAM 两大分支的详细比较 第一个 CUDA 程序之矩阵运算计算效能对比 Archlinux KDE Apache JMeter 配置高分屏缩放 解决 gitlab-runner 移除残留文件 permission denied nginx-ingress 配置路由 302 k8s 触发 pod 重新拉取镜像平滑升级的方法 Clickhouse 迁移后 permission denied 问题解决 Linux CPU 运行模式及功耗分析 Linux vim vi 翻页跳转命令快捷键 git 拉取所有 branch 和 tag 到本地并推送到远程 Rails 性能分析工具 rack-mini-profiler 和 bullet 全球国家、城市、地区开源数据库 Rails Active Record 常用命令 Rails Rake 简介与编写 如何调试 Vim 脚本 名侦探柯南松田阵平出场集数(最新1069话) 名侦探柯南妃英理出场集数(最新1069话) 《名侦探柯南》官方人气投票结果 名侦探柯南TV安室透出场集数(最新1110话) 名侦探柯南TV赤井秀一出场集数(更新至1194话) [转]名侦探柯南TV主线集数整理(截止1165集) 架构风格总结 [转译] 如何成为一个好的开发者? 【影评】名侦探柯南·零的执行人
使用 earlyoom 提前终止 Linux 高内存占用进程
Tianlun Song · 2024-11-20 · via Oskyla 烹茶室

本文 首发于 🌱 煎茶转载 请注明 来源

当我在服务器上运行一个不太重要的进程时,它的内存使用量会随实际情况不断发生变化,当它的内存超过某个阈值时,我想要 kill 掉它并重启该进程。为了满足我这个需求,我了解到了 earlyoom 这个程序。

earlyoom 是一个用于 Linux 的内存不足 (OOM) 守护进程。它在系统内存和交换空间不足时提前终止内存占用最大的进程,从而避免系统陷入完全无响应的状态。它的全称是 “Early OOM Daemon”,其中 OOM 代表 “Out Of Memory”。本文将介绍 earlyoom 的安装、配置和使用方法。

在 Linux 系统中,默认的 OOM 机制只有在内存和交换空间完全耗尽后才会触发,这通常会导致系统变得非常缓慢甚至完全无响应。earlyoom 的设计初衷是通过更早地检测内存和交换空间不足的情况,提前终止高内存占用的进程,从而保持系统的响应速度。

earlyoom 每秒最多检查 10 次内存和交换空间的使用情况。如果可用内存和可用交换空间均低于 10%,则终止内存占用最大的进程。这个阈值可以通过命令行参数进行配置。

earlyoom 的主要功能和特点

  1. 监控内存使用情况:earlyoom 会持续监控系统的可用内存和交换内存。通过定期检查内存使用情况,它能够在内存过低时及时采取措施。
  2. 主动释放内存:当系统内存降至预设的阈值以下时,earlyoom 会主动终止内存占用最高的进程。这比传统的 Linux 内核 OOM 杀手更早地介入,减少系统变得完全无响应的风险。
  3. 可配置性:用户可以通过命令行参数或配置文件自定义 earlyoom 的行为,包括设定内存和交换内存的阈值,选择是否终止内存占用最高的进程或是直接重启系统。
  4. 轻量级和高效:earlyoom 设计为一个轻量级的守护进程,占用系统资源非常少,适合在各种环境下运行。
  5. 日志和通知:earlyoom 会记录所有的内存监控和进程终止操作,并可以配置为在内存过低时发送通知,方便管理员及时了解系统状态。

earlyoom 的使用场景

  1. 避免系统冻结:在 Linux 系统中,当内存资源耗尽时,内核的 OOM (Out of Memory) Killer 会启动,尝试释放内存。默认情况下,OOM Killer 会在系统内存极度不足时才启动,这可能导致系统变得非常缓慢或完全无响应,用户无法进行操作。earlyoom 通过在内存和交换空间较低时更早地杀死进程,防止系统冻结,提高系统的稳定性和响应性。
  2. 提高系统的可用性:对于一些关键的服务器或应用场景,确保系统的稳定性至关重要。earlyoom 可以在内存紧张之前采取措施,避免系统进入不可操作的状态,尤其是在资源使用高峰期。
  3. 开发和测试环境:在开发和测试环境中,可能会出现由于内存泄漏或其他原因导致内存迅速耗尽的情况。使用 earlyoom 可以模拟和测试系统在低内存条件下的表现,确保应用程序能够在这些条件下稳定运行。

如何安装 earlyoom

从源码编译

首先,克隆 earlyoom 的 GitHub 仓库并进入项目目录:

git clone https://github.com/rfjakob/earlyoom.git
cd earlyoom

然后,编译项目:

可选:运行集成的自测试:

最后,使用 systemdinit.dearlyoom 注册为系统服务:

sudo make install              # systemd
sudo make install-initscript   # non-systemd

使用包管理器安装

Debian 和 Ubuntu

对于 Debian 10+ 和 Ubuntu 18.04+,可以直接安装 earlyoom 包:

sudo apt install earlyoom

Fedora 和 RHEL 8

对于 Fedora 和 RHEL 8(需要 EPEL):

sudo dnf install earlyoom
sudo systemctl enable --now earlyoom

Arch Linux

对于 Arch Linux:

sudo pacman -S earlyoom
sudo systemctl enable --now earlyoom

其他发行版的安装方法请参阅 repology 页面

如何使用 earlyoom

启动 earlyoom 可执行文件:

它会显示内存和交换空间的使用情况,并在内存和交换空间不足时终止进程。以下是一个示例输出:

earlyoom v1.8
mem total: 23890 MiB, user mem total: 21701 MiB, swap total: 8191 MiB
sending SIGTERM when mem avail <= 10.00% and swap free <= 10.00%,
        SIGKILL when mem avail <=  5.00% and swap free <=  5.00%
mem avail: 20012 of 21701 MiB (92.22%), swap free: 5251 of 8191 MiB (64.11%)
mem avail: 20031 of 21721 MiB (92.22%), swap free: 5251 of 8191 MiB (64.11%)
mem avail: 20033 of 21723 MiB (92.22%), swap free: 5251 of 8191 MiB (64.11%)
[...]

命令行选项

earlyoom 支持多种命令行选项,以下是常用选项的说明:

earlyoom v1.8
Usage: ./earlyoom [OPTION]...

  -m PERCENT[,KILL_PERCENT] 设置可用内存最小百分比 (默认 10%)。
                            低于此值发送 SIGTERM 信号,低于 KILL_PERCENT 时发送 SIGKILL 信号 (默认 PERCENT/2)。
  -s PERCENT[,KILL_PERCENT] 设置可用交换空间最小百分比 (默认 10%)。
  -M SIZE[,KILL_SIZE]       设置可用内存最小值 (以 KiB 计)。
  -S SIZE[,KILL_SIZE]       设置可用交换空间最小值 (以 KiB 计)。
  -n                        启用 d-bus 通知。
  -N /PATH/TO/SCRIPT        进程被杀死后执行脚本。
  -g                        杀死整个进程组。
  -d, --debug               启用调试信息。
  -v                        显示版本信息并退出。
  -r INTERVAL               内存报告间隔(以秒计,默认 1),设为 0 可禁用。
  -p                        设置 EarlyOOM 的 niceness 为 -20 和 oom_score_adj 为 -100。
  --ignore-root-user        不杀死 root 用户的进程。
  --sort-by-rss             按 RSS 大小选择进程而非 oom_score。
  --prefer REGEX            优先杀死符合正则表达式的进程。
  --avoid REGEX             避免杀死符合正则表达式的进程。
  --ignore REGEX            忽略符合正则表达式的进程。
  --dryrun                  干跑模式(不杀死任何进程)。
  --syslog                  使用 syslog 记录日志。
  -h, --help                显示帮助信息。

earlyoom 的命令行使用非常直观,可以通过不同的参数来配置它的行为。

注意事项:以上命令中正则表达式参数需要使用进程的comm名称

  • --prefer--avoid--ignore 参数中使用的正则表达式需要根据进程名称的前 15 个字节进行匹配,因为 comm 名称字段最大长度为 15 字节,超过部分会被截断。
  • 使用 --ignore 参数时需要特别小心,因为忽略某些关键进程可能会导致其他进程被杀死,从而影响系统的正常运行。

相关阅读:什么是进程的 comm 名称?Linux 进程 comm 名称详解

earlyoom 常用命令行使用示例

earlyoom 是一个内存管理工具,它可以在系统内存和交换空间低于设定阈值时提前杀死进程。以下是一些常用的命令行使用示例:

  1. 基本使用

    使用默认配置,设置内存和交换空间阈值为 10%。当内存和交换空间都低于 10% 时,earlyoom 会发送 SIGTERM,如果继续低于阈值,则发送 SIGKILL

  2. 自定义内存和交换空间阈值

    earlyoom -m 20,10 -s 15,7
    

    设置可用内存阈值为 20%,当内存低于 20% 时发送 SIGTERM,低于 10% 时发送 SIGKILL。同时,设置交换空间阈值为 15%,低于 15% 时发送 SIGTERM,低于 7% 时发送 SIGKILL

  3. 指定内存和交换空间的绝对值

    earlyoom -M 1048576,524288 -S 512000,256000
    

    设置内存阈值为 1 GiB (1048576 KiB),低于此值时发送 SIGTERM,低于 512 MiB (524288 KiB) 时发送 SIGKILL。交换空间阈值为 500 MiB (512000 KiB),低于此值时发送 SIGTERM,低于 250 MiB (256000 KiB) 时发送 SIGKILL

  4. 启用调试模式

    启用调试信息输出,帮助排查问题。

  5. 启用通知

    启用通过 D-Bus 发送通知。需要 systembus-notify 工具运行在用户会话中,以显示通知。

  6. 执行脚本

    earlyoom -N /path/to/script.sh
    

    在每次进程被杀死时执行指定的脚本。脚本可以获取被杀死进程的相关信息,如 PID、进程名、命令行等。

  7. 增加优先级

    增加 earlyoom 的优先级,将其 niceness 设置为 -20,并将 oom_score_adj 设置为 -100。需要通过系统服务配置来达到相同效果。

  8. 模拟运行

    模拟运行 earlyoom,不实际杀死任何进程,用于测试配置是否正确。

  9. 忽略某些进程

    earlyoom --ignore '^gnome-shell$'
    

    --ignore 参数用于完全忽略名称匹配指定正则表达式(REGEX)的进程。这意味着这些进程无论内存使用情况如何,都不会被 earlyoom 杀死。使用此选项时需要谨慎,因为忽略某些进程可能会导致其他进程被优先选择进行杀死,从而影响系统的稳定性。

  10. 优先杀死某些进程

    earlyoom --prefer '^Isolated Web Co$'
    

    --prefer 参数用于优先杀死名称匹配指定正则表达式(REGEX)的进程。当某个进程的名称与给定的正则表达式匹配时,会在其 oom_score 中增加 300 分,这使得该进程更有可能被优先选择进行杀死。

  11. 避免杀死某进程

    ```sh
    earlyoom --avoid '^gunicorn$'
    ```
    

    --avoid 参数用于避免杀死名称匹配指定正则表达式(REGEX)的进程。当某个进程的名称与给定的正则表达式匹配时,会在其 oom_score 中减少 300 分,这使得该进程不太可能被选择进行杀死。

earlyoom 退出状态码

  • 0: 成功执行。
  • 1: 其他错误 - 检查错误消息以获取详细信息。
  • 2: 开关冲突 - 使用了不兼容的选项。
  • 4: 无法切换到 /proc 目录。
  • 5: 无法打开 /proc 目录。
  • 7: 无法打开 /proc/sysrq-trigger
  • 13: 未知选项 - 传递了无效的选项。
  • 14: 其他选项的参数错误。
  • 15: 内存阈值参数错误。
  • 16: 交换空间阈值参数错误。
  • 102: 无法打开 /proc/meminfo 文件。
  • 103: 无法读取 /proc/meminfo 文件。
  • 104: /proc/meminfo 文件中找不到特定条目。
  • 105: 解析 /proc/meminfo 文件内容时转换数字失败。

配置文件

如果你将 earlyoom 作为系统服务运行,可以通过 /etc/default/earlyoom 文件调整其配置。例如:

EARLYOOM_ARGS="-m 5 -r 60 --avoid '(^|/)(init|Xorg|ssh)$' --prefer '(^|/)(java|chromium)$'"

修改配置文件后,重新启动服务以应用更改:

systemctl restart earlyoom

测试 earlyoom

可以通过制造内存泄漏(切记不要在生产环境测试)来测试 earlyoom 的功能:

查看日志

如果 EarlyOOM 作为 systemd 服务运行,可以通过以下命令查看最近的日志:

systemctl status earlyoom

或者查看详细日志:

sudo journalctl -u earlyoom -g "(sending|killing)" --since today

示例输出:

8月 05 00:53:43 32.3.18.8 earlyoom[3147772]: sending SIGTERM to process 1389844 uid 0 "Isolated Web Co": badn>
8月 05 02:25:59 32.3.18.8 earlyoom[3147772]: sending SIGTERM to process 1419894 uid 0 "Isolated Web Co": badn>
8月 05 03:52:30 32.3.18.8 earlyoom[3147772]: sending SIGTERM to process 1448534 uid 0 "Isolated Web Co": badn>
8月 05 05:18:24 32.3.18.8 earlyoom[3147772]: sending SIGTERM to process 1476938 uid 0 "Isolated Web Co": badn>
8月 05 06:48:10 32.3.18.8 earlyoom[3147772]: sending SIGTERM to process 1505535 uid 0 "Isolated Web Co": badn>
8月 05 08:13:19 32.3.18.8 earlyoom[3147772]: sending SIGTERM to process 1535267 uid 0 "Isolated Web Co": badn>
8月 05 09:40:01 32.3.18.8 earlyoom[3147772]: sending SIGTERM to process 1563244 uid 0 "Isolated Web Co": badn>
8月 05 10:32:45 32.3.18.8 earlyoom[1609353]: Will avoid killing process names that match regex '(init|sshd|su>
8月 05 10:32:45 32.3.18.8 earlyoom[1609353]: sending SIGTERM when mem <= 10.00% and swap <= 10.00%,

启用通知

从 1.6 版本开始,earlyoom 可以通过 d-bus 发送通知。需要启用 -n 选项,并运行 systembus-notify

此外,earlyoom 可以在每次终止进程后执行脚本,使用 EARLYOOM_PIDEARLYOOM_UIDEARLYOOM_NAME 环境变量提供进程信息。使用 -N /path/to/script 启用此功能。

发送通知到企业微信示例脚本:

#!/bin/bash

# 企业微信 webhook 地址
WEBHOOK_URL='https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx'

# 生成通知内容
CONTENT="进程被EarlyOOM杀死\n\n"
CONTENT+="PID: $EARLYOOM_PID\n"
CONTENT+="进程名: $EARLYOOM_NAME\n"
CONTENT+="命令行: $EARLYOOM_CMDLINE\n"
CONTENT+="UID: $EARLYOOM_UID"

# 发送通知
curl -X POST "$WEBHOOK_URL" \
     -H "Content-Type: application/json" \
     -d "{
           \"msgtype\": \"text\",
           \"text\": {
               \"content\": \"$CONTENT\"
           }
     }"

结论

earlyoom 是一个简单而有效的工具,可以帮助 Linux 用户避免由于内存不足而导致的系统无响应问题。通过提前检测和终止高内存占用的进程,earlyoom 保持系统的稳定性和响应速度。如果你经常遇到系统内存不足的问题,推荐试试 earlyoom

References

#GNU_Linux #Debian #earlyoom