You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Linux 4.10生产环境OOM Killer未回收页缓存却杀进程求助

Linux 4.10服务器高负载下clone()内存分配失败触发OOM Killer的排查与解决

嘿,我之前在生产环境里碰到过几乎一模一样的问题,咱们来一步步拆解这个麻烦事儿,找出根因和解决办法。

首先你提到的free -m显示可用内存只剩1-3GB,但64GB总内存里大部分“消失”了——这大概率是被页缓存(Page Cache)或者Slab内核缓存占用了。Linux本来会把空闲内存拿来缓存磁盘数据提升性能,理论上需要的时候能快速释放给应用,但高负载下往往会出现几种“卡壳”情况:

可能的根因

  • 内存碎片化严重:长期高负载运行后,内存被拆成了一堆小空闲块,而clone()创建进程时需要连续的内存块(比如栈空间),哪怕总空闲内存够,没足够的连续块就会分配失败,直接触发OOM Killer。
  • Slab缓存“僵死”:Slab是内核用来缓存常用对象(比如文件句柄、进程描述符)的,要是某些应用或内核模块疯狂创建这类对象又不释放,Slab占的内存就会被“钉死”,没法回收给用户空间。
  • OOM Killer策略或内存过度承诺坑:Linux 4.10的OOM机制可能没优先尝试释放缓存就直接杀进程;或者你的系统开了内存过度承诺,平时看起来内存够用,真要分配的时候才暴露出缺口。

一步步排查与解决

第一步:先搞清楚内存到底去哪了

别光看free -m,用这些命令深挖内存分布:

  • 执行cat /proc/meminfo,重点看这几个指标:
    • Cached:页缓存占的内存
    • SReclaimable/SUnreclaim:可回收/不可回收的Slab内存
    • CommitLimitCommitted_AS:看是不是内存过度承诺超了
  • slabtop实时看Slab缓存的占用,比如dentry(目录项缓存)、inode_cache(inode缓存)是不是占了大头
  • pmap -x <Web进程PID>查看Web进程的内存细节,排查有没有内存泄漏

第二步:检查内存碎片化程度

执行这个命令看内存块的分布:

cat /proc/buddyinfo

如果输出里Normal区(普通内存区)的大空闲块(比如order 3及以上,对应8KB+的块)数量极少,那就是碎片化严重导致的连续内存块不足。

第三步:临时调整内核参数救急

这些参数可以临时生效(用sysctl -w),要永久生效就写到/etc/sysctl.conf里:

  • 优先回收内核缓存:
    sysctl -w vm.vfs_cache_pressure=200  # 默认100,调高到200让内核优先回收目录和inode缓存
    sysctl -w vm.page-cluster=0  # 减少连续内存页的分配,缓解碎片化
    
  • 调整内存过度承诺策略:
    如果当前vm.overcommit_memory是默认的0,改成2并设置合理的比例(比如90,允许用90%的物理内存+交换区):
    sysctl -w vm.overcommit_memory=2
    sysctl -w vm.overcommit_ratio=90
    
  • 手动整理内存碎片:
    Linux 4.10支持内存压缩整理,执行这个命令手动触发一次:
    sysctl -w vm.compact_memory=1
    sysctl -w vm.zone_reclaim_mode=1  # 让内核在内存紧张时优先回收当前内存区的资源
    

第四步:让OOM Killer别乱杀Web进程

  • 给Web进程设置更低的OOM评分(数值越小,越不容易被盯上):
    echo -1000 > /proc/<你的Web进程PID>/oom_score_adj
    
    可以把这个命令加到Web应用的启动脚本里,确保每次启动都生效。
  • 或者让OOM Killer优先杀触发问题的进程(比如那个cron任务):
    sysctl -w vm.oom_kill_allocating_task=1
    

第五步:长期根治方案

  • 升级内核:Linux 4.10是2017年的老版本了,后续的长期支持版本(比如4.19、5.4)在内存管理、碎片化处理和OOM机制上做了超多优化,升级能从根源减少这类问题。
  • 排查Web应用内存泄漏:如果Web进程内存只增不减,哪怕回收缓存也顶不住,用valgrind或者应用自带的内存分析工具找泄漏点。
  • 错峰执行定时任务:把cron任务挪到Web服务器低负载的时间段(比如凌晨),避免高负载时抢内存。

内容的提问来源于stack exchange,提问作者Confused

火山引擎 最新活动