Linux kernel oom-killer报错分析
最近调试xilinx嵌入式程序是遇到了内存泄露导致oom-killer报错的问题。今天花点时间,做一个简单总结。这个打印是的日志,意思是系统物理内存耗尽时,内核强制终止了一个进程以释放内存。

最近调试xilinx嵌入式程序是遇到了内存泄露导致oom-killer报错的问题。今天花点时间,做一个简单总结。报错信息如下:
[14407.349660] app invoked oom-killer: gfp_mask=0x100cca(GFP_HIGHUSER_MOVABLE), order=0, oom_score_adj=0
[14407.349673] CPU: 3 PID: 333 Comm: app Tainted: G O 5.10.0-xilinx-v2021.2 #1
[14407.350211] oom-kill:constraint=CONSTRAINT_NONE,nodemask=(null),cpuset=/,mems_allowed=0,global_oom,task_memcg=/system.slice/rc-local.service,task=app,pid=333,uid=0
[14407.350312] Out of memory: Killed process 333 (app) total-vm:4820588kB, anon-rss:2848716kB, file-rss:0kB, shmem-rss:0kB, UID:0 pgtables:8384kB oom_score_adj:0
[14408.115832] oom_reaper: reaped process 333 (app), now anon-rss:16kB, file-rss:3296kB, shmem-rss:0kB
这个打印是Linux OOM Killer(内存不足杀手)的日志,意思是系统物理内存耗尽时,内核强制终止了一个进程以释放内存。
一、日志关键信息解读
日志里的核心字段对应被杀死进程的内存使用和状态:
-
Out of memory: Killed process 333 (app):系统内存不足,杀死了PID=333、名为app的进程。 -
total-vm:4820588kB:进程的虚拟内存总量(包括未实际加载到物理内存的部分,比如映射的文件、预留的地址空间),约4.8GB。 -
anon-rss:2848716kB:进程的匿名页常驻内存(即实际占用物理内存的部分,比如堆、栈、动态分配的内存),约2.8GB——这是导致OOM的关键(因为匿名内存无法通过回收文件缓存释放)。 -
oom_score_adj:0:进程的OOM调整分数(范围-1000~1000),0表示默认优先级(分数越高越容易被杀)。
二、OOM Killer的决策逻辑
当系统可用物理内存+Swap空间不足以分配新内存时,OOM Killer会根据oom_score(由oom_score_adj、内存占用、进程运行时间等计算)选择得分最高的进程杀死。
你的app进程被杀的核心原因是:它的匿名内存占用(2.8GB)过大,加上系统总内存/ Swap不足,导致其oom_score最高。
三、原因分析
产生这个问题的原因是我的app程序存在内存泄露,运行一段时间后,系统内存耗尽,触发了oom-killer程序。
四、解决思路与步骤
1. 先确认系统内存状态
-
用
free -h查看物理内存和Swap的使用情况:比如如果
available列接近0,说明内存几乎耗尽;如果Swap列很小(比如<1GB),需要扩容。 -
用
dmesg | grep -i "oom"查看更详细的OOM日志,确认当时系统的内存阈值和被杀进程的得分。
2. 排查App的内存泄漏
-
工具检测:
-
用
valgrind --leak-check=full ./app(需交叉编译Valgrind到ARM)检测C/C++代码的内存泄漏; -
Qt程序可以用
Qt Creator的内存分析器(Memory Analyzer)跟踪对象生命周期和内存占用; -
用
top/htop实时监控App的内存变化(看RES列是否持续增长)。
-
-
代码审查:重点检查动态内存分配(
malloc/new)、Qt对象树(确保父子关系正确)、缓存机制(比如是否有无限增长的缓存列表)。
3. 调整OOM策略(临时缓解)
如果App是关键进程,不想被OOM Killer杀死,可以调整其oom_score_adj:
# 将app进程的oom_score_adj设为-1000(永远不会被杀,但需谨慎!)
echo -1000 > /proc/$(pgrep app)/oom_score_adj
⚠️ 注意:这会让App即使占用大量内存也不会被杀,可能导致系统卡死,仅建议临时测试用。
4. 增加内存资源
-
启用Swap分区:如果没开Swap,可以用
fallocate创建Swap文件并启用:sudo fallocate -l 2G /swapfile # 创建2GB Swap文件 sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile # 永久生效:将/swapfile swap swap defaults >> /etc/fstab -
升级设备内存:如果是ZynqMP开发板,可以选择更大RAM的型号(比如ZCU104有4GB PS RAM,ZCU106也有类似配置)。
5. 优化App内存使用
-
减少不必要的动态分配:比如用栈内存代替堆内存(小对象)、复用对象池(比如视频帧缓冲区)。
-
限制内存占用:比如Qt程序可以设置
QApplication::setMaximumCacheSize限制图像缓存;C++程序可以用setrlimit限制进程的虚拟内存或物理内存上限。 -
使用更高效的存储方式:比如用
mmap映射文件代替直接读入内存,或者用稀疏数据结构(比如只存储非零数据)。
五、总结
oom-killer问题本质是App的内存占用超过了嵌入式设备的内存容量,导致OOM Killer介入。优先排查App的内存泄漏和优化内存使用,其次考虑增加Swap或升级硬件。

惠州西湖
更多推荐



所有评论(0)