当前位置: 首页 > news >正文

【内存优化】内存优化以及 oom 排查整体思路

标签: oom-kill, 内存优化, 堆, 栈, 数据段, 代码段, glibc缓存

前言

在嵌入式 LinuxC 设备开发中,内存资源往往非常紧张。不同于服务器动辄几十上百 GB 的内存,嵌入式设备可能只有 256MB、512MB 甚至更少。当系统内存不足时,Linux 内核会启动OOM Killer(Out-Of-Memory Killer)机制,选择性地杀死某个进程来回收内存。对于用户来说,这表现为"程序突然闪退",是典型的"死机"体验。

本文将系统性地介绍 OOM 问题的排查思路和内存优化方法,从内核机制到实际代码,给出完整的解决方案。

一、OOM-Kill 机制原理

1.1 内核的内存分配策略

Linux 内核的内存分配有一个关键特性:overcommit(过度提交)。也就是说,进程调用malloc()申请内存时,内核并不会立即分配实际的物理内存,而是只记录一个"承诺",等到进程真正访问(读/写)这块内存时才分配物理页。

这个行为由/proc/sys/vm/overcommit_memory控制:

# 0 - 启发式 overcommit(默认),内核会拒绝"明显不合理"的申请cat/proc/sys/vm/overcommit_memory# 输出: 0# 1 - 总是允许 overcommit,不做任何检查echo1>/proc/sys/vm/overcommit_memory# 2 - 严格模式,不允许 overcommit# 总提交量不超过 swap + RAM * overcommit_ratioecho2>/proc/sys/vm/overcommit_memorycat/proc/sys/vm/overcommit_ratio# 输出: 50

1.2 OOM 评分机制

当系统真的没有可用物理内存了,内核会启动 OOM Killer,选择一个"最适合被杀"的进程。这个选择过程由oom_scoreoom_score_adj决定:

# 查看某个进程的 oom_scorecat/proc/<pid>/oom_score# 查看 oom_score_adj(范围 -1000 到 1000)cat/proc/<pid>/oom_score_adj# 设置某个关键进程不被 OOM Killer 杀掉echo-1000>/proc/<pid>/oom_score_adj# 设置某个进程优先被杀echo1000>/proc/<pid>/oom_score_adj

oom_score的计算主要考虑因素:

  • 进程使用的物理内存占总内存的比例
  • 进程的存活时间(新进程更容易被杀)
  • 进程是否是 root 用户启动(root 进程有一定的保护)
  • oom_score_adj的手动调整值

1.3 触发条件

OOM Killer 的触发不仅看物理内存,还要看 swap 和水位线(watermark):

# 查看内存水位线(low/min/high)cat/proc/zoneinfo|grep-A5"Node 0, zone"# 查看当前内存状态cat/proc/meminfo# 关注 MemFree, MemAvailable, SwapFree

当内存低于min水位线且无法通过回收(kswapd)恢复到low水位线以上时,就会触发 OOM Killer。

二、分析 OOM 日志

当 OOM Killer 被触发时,内核会在dmesg中输出详细的日志信息。这是排查 OOM 问题的第一手资料。

2.1 典型的 OOM 日志

[12345.678] my_daemon invoked oom-killer: gfp_mask=0x6200ca(GFP_HIGHUSER_MOVABLE), order=0 [12345.679] Mem-Info: [12345.680] active_anon:51200 inactive_anon:30720 isolated_anon:0 [12345.680] active_file:1024 inactive_file:512 isolated_file:0 ... [12345.690] [ pid ] uid total_vm rss pgtables swapents oom_score_adj name [12345.691] [ 123] 0 128000 64000 512 0 0 my_daemon [12345.692] [ 456] 0 32000 16000 128 0 0 other_proc ... [12345.700] Out of memory: Killed process 123 (my_daemon) total-vm:512000kB, anon-rss:256000kB, file-rss:0kB

2.2 关键信息提取

从 OOM 日志中需要关注以下关键信息:

# 提取 OOM 相关日志dmesg|grep-i"oom\|out of memory\|killed process"|tail-20# 查看被杀进程的详细信息dmesg|grep-A20"Out of memory: Killed"# 提取被杀进程的 RSS(实际使用的物理内存)dmesg|grep"Killed process"|awk'{print $5, $6, $7, $8, $9}'

重点关注:

    http://www.jsqmd.com/news/615661/

    相关文章:

  • 第04章-开源鸿蒙的架构概览
  • OpenClaw批量操作:千问3.5-27B处理100+文件重命名任务
  • Yarn三种调度器详解及默认调度器说明
  • stock-sdk-mcp 的实践整理绰
  • Kafka、ES、Flink、Spark 如何撑起高并发大数据平台?
  • Linux相关概念和易错知识点(52)(基于System V的信号量和消息队列)
  • F-Theta扫描透镜的性能评估
  • 2026年垃圾中转站设备优质推荐榜:移动垃圾压缩站、竖直直压式垃圾站、压缩垃圾中转站、地埋式垃圾压缩站、垂直式垃圾压缩站选择指南 - 优质品牌商家
  • [AI/向量数据库/GUI] Attu : Milvus 的图形化与一体化管理工具勇
  • 如何实现一个可插入自定义标签的文本输入框
  • 从零构建可审计、可回滚、可监控的向量检索服务:EF Core 10架构设计图+DDD分层实践(含GitHub可运行Demo)
  • 2026档案室密集柜推荐榜:档案室用密集柜/档案智能密集柜/橱式密集柜/电动密集柜/电动密集档案柜/移动档案密集柜/选择指南 - 优质品牌商家
  • OpenClaw插件开发:为Qwen3-14b_int4_awq添加钉钉通道支持
  • 电容是什么?一个“快充快放”的微型充电宝坷
  • 毕业设计实战:基于SSM+MySQL的社区医疗服务预约管理系统设计与实现指南
  • 别再踩坑了!SQL Server数据类型那点事儿,看懂这篇少背三个锅竟
  • 嵌入式系统开发:硬件思维与架构实践
  • 一个进程是 host root vs docker root
  • Linux I/O 演进史:从管道到零拷贝,一篇串起个服务端核心原语纠
  • OpenClaw技能组合策略:Qwen3-32B在复杂工作流中的模块化调用
  • 金融PHP支付配置终极Checklist(2024Q3央行金融科技新规适配版):58项必检条目,漏1项即触发监管通报
  • 绵阳高新区小学晚托自习
  • A Gift from the Integration of Discriminative andDiffusion-based Generative Learning: BoundaryRefi
  • OpenClaw配置备份指南:gemma-3-12b-it环境快速迁移与恢复
  • 嵌入式文件传输协议选型与优化实践
  • OpenClaw备份恢复方案:Qwen3-32B任务历史与技能配置迁移
  • OpenClaw代码审查:Qwen3.5-9B自动化质量检查
  • 2026武汉高评价日常保洁TOP10推荐:武汉物业保洁公司/武汉企业保洁公司/武汉保洁公司/武汉保洁外包公司/武汉保洁托管公司/选择指南 - 优质品牌商家
  • 嵌入式通信协议的状态机接收模块设计与优化
  • 2026年可靠熔体流动速率仪TOP推荐:简支梁冲击试验机/落锤冲击试验机/制样机/差热/差示扫描量热仪/开闭孔率测定仪/选择指南 - 优质品牌商家