Linux服务器内存不足,最直接有效的办法是按“定位-回收-防护”三步走:先用命令找出内存消耗的根源,再针对进程、缓存或Swap进行安全清理,最后通过配置监控和调优参数来防止问题复发。
排查内存消耗的根源
“内存不足”是一个笼统的说法,在动手清理之前,必须搞清楚内存到底被谁吃掉了,盲目执行kill命令或者重启服务,很可能误伤正常业务进程。
查看整体内存水位
使用free -h命令可以快速查看物理内存和Swap的使用概况,重点关注available(可用内存)这一列,它比used更真实地反映了系统还能分配多少内存,当available长期低于总内存的10%,且Swap的si、so两列数值持续增长时,基本可以确认内存处于紧张状态。
定位具体消耗进程
命令top进入交互界面后,按Shift+P按CPU排序,按Shift+M按内存排序,但top有一个局限它只显示动态分配的物理内存,不包含共享内存和Cache,要更精确地衡量单个进程的常驻内存,推荐使用ps aux --sort=-%mem,直接按内存占用率降序排列,一目了然。
一个经常被忽略的细节是,每个进程占用的内存不止自己那部分,比如启动了一个Java应用,JVM堆外内存、线程栈、元空间都会消耗额外资源,这时候用smem工具(需单独安装)可以统计更接近真实的USS/PSS值。
检查OOM Killer日志
如果系统日志里频繁出现“Out of memory: Kill process”字样,说明内核的OOM Killer已经在被动杀进程了,这类记录通常位于/var/log/messages或/var/log/syslog,看到这个日志,意味着内存不足已经到了相当严重的程度,后续排查要侧重于内存泄漏或配置超额,而不是简单的临时清理。
场景模拟
想象一下:服务器运行着MySQL和Nginx,访问量突然翻倍,MySQL的缓冲池不够用,开始大量使用临时表,你执行free -h发现内存耗尽,ps aux --sort=-%mem看到mysqld占了70%内存,如果MySQL的buffer pool配置(innodb_buffer_pool_size)设置过高,比如占了系统总内存的80%,那么即使强行腾出一点内存,很快又会耗尽。
清理已定位的内存
关键原则:优先清理Cache和Swap,谨慎杀掉进程,进程是业务的核心,杀掉很可能导致服务中断,Cache和Swap是内核自我管理的资源,它们的回收不会对业务产生直接影响。

回收Page Cache
Linux内核会把读写过的文件缓存到Page Cache里,这部分内存标记为buff/cache,当系统内存紧张时,内核通常会自动回收,但有些场景下(比如刚进行完大量文件复制、备份解压),Cache会短期占据大量空间。
- 执行
sync命令将脏页数据落盘 - 执行
echo 1 > /proc/sys/vm/drop_caches释放Page Cache - 执行
echo 2 > /proc/sys/vm/drop_caches释放dentries和inodes缓存 - 执行
echo 3 > /proc/sys/vm/drop_caches同时释放以上两者
业内专家指出:生产中尽量使用
echo 1或echo 3,且确认系统没有正在写入大量数据的任务,否则可能造成轻微的I/O性能抖动。
调整Swap使用策略
Swap是磁盘上的交换分区,内存不足时会作为应急空间,但Swap频繁读写会让系统性能断崖式下跌,有两个参数值得调整:
- vm.swappiness(默认60):数值越小,系统越倾向于使用物理内存,临时调整执行
sysctl vm.swappiness=10,永久生效需写入/etc/sysctl.conf - vm.min_free_kbytes:保留最小空闲内存,适当调大(比如设为物理内存的0.5%-1%)可以避免内存临界时的分配卡顿
如果当前Swap空间本身设置过小(比如只有512MB),用free -h确认后,需要新增Swap文件,创建步骤为:
dd if=/dev/zero of=/swapfile bs=1G count=4(创建4GB文件)chmod 600 /swapfile(严格权限)mkswap /swapfile(格式化为Swap)swapon /swapfile(激活)- 写入
/etc/fstab实现开机挂载
处理失控进程
如果你发现某个进程的RES内存持续增长,重启后不久又涨回来,这大概率是内存泄漏,配合ps aux | grep java之类的命令确认项目名后,在业务低峰期进行重启,并联系研发排查代码逻辑,这里要区分:如果是预期内的占用大(比如Elasticsearch吃掉大量堆内存作为缓存),不叫泄漏,叫配置不合理。
系统性优化内存占用
临时清理只能解除燃眉之急,真正的linux服务器内存不足解决方案在于合理的资源规划和调优。
调整核心应用的内存参数
不同应用的调整方向差异很大,详情参考下表:
| 类型 | 常见示例 | 关键参数 | 建议操作 |
|---|---|---|---|
| JVM应用 | Java服务、Hadoop | -Xms、-Xmx | 堆内存尽量设置成相同大小(-Xms=-Xmx),避免运行时动态扩容导致的内存抖动 |
| 数据库 | MySQL、PostgreSQL | buffer_pool_size、shared_buffers | 通常调整为物理内存的50%-60%,通过SHOW STATUS观察实际使用率再微调 |
| Web服务器 | Nginx、Apache | worker_processes | 按CPU核心数设定,不必每请求占满所有内存 |
| 消息队列 | Redis、Kafka | maxmemory、堆外内存 | Redis内存紧凑存储,Kafka的页缓存占用高但可回收 |
限制进程的内存使用上限
Linux的CGroups是容器化技术的基石,也可用于限制普通进程,通过systemd运行的服务,可以在unit文件中添加MemoryMax=或MemoryLimit=参数。
[Service]
MemoryMax=2G
MemorySwapMax=1G
这样即使进程出现内存膨胀,也会在触顶时被内核强制回收,而不是拖垮整个服务器。
应用层排障逻辑
如果是自研代码,内存优化方向集中在:
- 大对象复用:频繁创建大数组或大字符串容易造成GC压力,尽量使用对象池
- 连接池上限:数据库连接、HTTP连接池默认值往往偏大,一个连接至少2MB背景内存,100个连接就是200MB
- 日志缓冲:异步日志和合理的缓冲队列能显著降低内存碎片化
内存告警与周期预防
靠人工盯着free命令不现实,尤其是生产环境的集群服务器,配置监控是必要的。
扎实用好监控工具
- Prometheus + node_exporter:采集node_memory_MemAvailable_bytes等指标
- Zabbix:自带模板即可监控物理内存、Swap使用率,设置触发器告警
- 云厂商监控:简米云、酷番云的云监控控制台可以设置内存使用率阈值(比如连续5分钟超过85%)
告警规则建议分级:内存使用率>75%属于关注,>90%属于严重,Swap使用率>50%且持续增长属于危险。
定期巡检脚本
将以下命令组合成一个巡检脚本,配合cron定时执行:
free -h
ps aux --sort=-%mem | head -15
ss -s
cat /proc/meminfo
dmesg | grep -i "out of memory"
脚本每次运行时将输出追加到日志文件,积累2-4周数据后,可以清楚地判断内存占用是否存在周期性峰值或缓慢上升趋势。

换高配还是做减法?
当优化到极限仍然经常内存不足,需要考虑升级硬件或重新架构,行业共识是,按业务规模估算内存需求居多且并发不高的场景,8GB内存足够;涉及大量数据库查询、缓存热数据、生产级JVM服务,建议32GB起步;数据量达到亿级别且经常做宽表聚合,直接上64GB以上,或者引入分布式方案。
两个典型场景的实战走查
场景A:测试环境频繁卡死,free显示内存全满
排查发现是开发人员把多个JVM测试服务同时跑在一台4GB机器上,每个应用默认的-Xmx都是物理内存的1/4,解决方式:修改启动脚本,根据物理内存和JVM数量合理分配堆,微服务demo占用的堆内存控制在512MB以内。
场景B:Nginx服务器响应变慢,free -h显示buff/cache占了80%
执行echo 3 > /proc/sys/vm/drop_caches后,可用内存恢复,但过了几小时又出现了,这说明业务产生的文件访问量太大,单纯依赖手动回收不合理,正确做法是调整sysctl配置,适当压低vm.dirty_ratio,或者对Nginx的open_file_cache进行超时设限。
相关问答
linux服务器内存不足有哪些常用排查命令?
首选free -h看整体情况,再用ps aux --sort=-%mem定位进程,ss -s确认网络连接数量是否异常。cat /proc/meminfo可以查看内核内存的细项分配,涉及容器场景时还需要docker stats观察容器维度的内存消耗。
为什么linux服务器内存不足时,优先清理缓存而不是杀进程?
因为缓存(Cache)是内核根据访问热度主动缓存的文件数据,它属于“可压缩”内存,杀掉业务进程会直接导致连接断开、任务失败,而清理缓存只是失去热点文件的加速效果,数据仍在磁盘上,不影响系统功能,但需要警惕的是:如果清理缓存后内存很快又被占满,说明业务内存需求已经超出硬件可承受范围,这是扩容或缩减业务的信号。
linux服务器内存不足怎么处理Swap空间不够的问题?
确认现有Swap分区大小swapon --show,如果已经设置为物理内存的1-2倍仍然频繁swap,说明物理内存严重不足,扩充Swap只是饮鸩止渴,临时扩容可以创建Swap文件,但长期方案还是优先降低应用内存占用,最后考虑物理内存扩容,简米云和酷番云的大部分实例规格支持在线扩容内存,重启后生效。
图片来源于AI模型,如侵权请联系管理员。作者:酷小编,如若转载,请注明出处:https://www.kufanyun.com/ask/856625.html


评论列表(3条)
这篇文章写得非常好,内容丰富,观点清晰,让我受益匪浅。特别是关于执行的部分,分析得很到位,给了我很多新的启发和思考。感谢作者的精心创作和分享,期待看到更多这样高质量的内容!
@月月3869:读了这篇文章,我深有感触。作者对执行的理解非常深刻,论述也很有逻辑性。内容既有理论深度,又有实践指导意义,确实是一篇值得细细品味的好文章。希望作者能继续创作更多优秀的作品!
@甜星4636:读了这篇文章,我深有感触。作者对执行的理解非常深刻,论述也很有逻辑性。内容既有理论深度,又有实践指导意义,确实是一篇值得细细品味的好文章。希望作者能继续创作更多优秀的作品!