[root@localhost ~]# free -mtotal used free shared buff/cache available
Mem: 31208 14317 1280 1551 15610 14657
Swap: 15927 2781 13146
[root@localhost ~]#
從 free -m
輸出來看,當前系統并非物理內存完全耗盡(物理內存 free 為 1280MB,available 為 14657MB),但存在「內存使用偏高、空閑內存較少」的情況。核心原因是 Linux 會主動利用空閑內存作為 buff/cache
(緩存文件/目錄元數據、磁盤讀寫數據)以提升性能,因此需先區分「真實內存不足」和「緩存占用過高」,再針對性處理。
一、先理解當前內存狀態(關鍵指標解讀)
指標 | 數值(MB) | 含義解讀 |
---|---|---|
total | 31208 | 物理內存總大小(約 30.5GB) |
used | 14317 | 已被進程實際占用的內存(不含緩存) |
free | 1280 | 完全空閑的內存(未被任何進程/緩存使用) |
buff/cache | 15610 | 緩存(page cache)+ 緩沖區(buffer),可被內核主動回收(不影響進程) |
available | 14657 | 真正可分配給新進程的內存(= free + 可回收的 buff/cache),當前充足 |
Swap used | 2781 | 已使用的交換分區(約 2.7GB),說明部分內存數據已交換到磁盤(需關注) |
二、分場景處理方案
場景1:臨時釋放緩存(buff/cache 占用過高,需快速騰內存)
Linux 的 buff/cache
是「可回收資源」,當系統需要內存時內核會自動回收,但也可手動觸發釋放(無風險,不影響運行中進程)。
執行以下命令釋放緩存(需 root 權限):
# 1. 釋放頁緩存(page cache,最主要的緩存類型)
echo 1 > /proc/sys/vm/drop_caches# 2. 釋放頁緩存 + 目錄項緩存(dentries)+ inode 緩存
echo 2 > /proc/sys/vm/drop_caches# 3. 釋放所有可回收緩存(推薦,釋放最徹底)
echo 3 > /proc/sys/vm/drop_caches
執行后再次用 free -m
查看,會發現 free
內存增加,buff/cache
減少(例如從 15GB 降至幾 GB)。
場景2:排查高內存占用進程(找到“內存大戶”)
若 used
內存持續過高(如超過 80%),需定位具體是哪些進程消耗內存,判斷是否為異常占用(如內存泄漏、不合理的進程配置)。
步驟1:查看進程內存占用(按內存使用率排序)
# 方法1:用 top 實時查看(按「M」鍵切換為內存使用率排序)
top# 方法2:用 ps 輸出詳細內存占用(按 %MEM 降序,顯示前20個進程)
ps -aux --sort=-%mem | head -n 20
關鍵指標解讀(ps 輸出中):
%MEM
:進程占用的物理內存百分比(核心參考);VSZ
:進程虛擬內存大小(含共享庫、交換區,參考意義低);RSS
:進程實際占用的物理內存大小(不含緩存,真實內存消耗)。
處理高內存進程:
-
正常進程(如數據庫、應用服務):
若進程內存增長合理(如 MySQL 緩存數據),可檢查其配置是否過高(例如 JVM 的-Xmx
設太大、MySQL 的innodb_buffer_pool_size
超過物理內存 50%),適當下調配置(需重啟進程生效)。 -
異常進程(如無名進程、內存泄漏進程):
若進程無正常用途(如僵尸進程、惡意進程),或內存持續增長不釋放(內存泄漏),可先嘗試優雅停止(如systemctl stop 服務名
),若無法停止則強制殺死(kill -9 進程PID
),并排查進程來源(避免再次啟動)。
場景3:優化交換分區(Swap)使用
當前 Swap 已使用 2.7GB,若物理內存仍充足卻頻繁使用 Swap,會導致系統性能下降(磁盤速度遠慢于內存),需調整內核參數減少 Swap 依賴。
1. 查看當前 Swap 使用率和內核參數
# 查看 Swap 詳細使用(哪些進程用了 Swap)
for i in $(cd /proc; ls -d [0-9]*); do echo -n "$i "; grep VmSwap /proc/$i/status 2>/dev/null; done | sort -k 2 -n -r | head -n 10# 查看內核 Swap 調整參數(swappiness)
cat /proc/sys/vm/swappiness
swappiness
含義:內核使用 Swap 的傾向,取值 0-100(值越高越容易用 Swap);
推薦設置:物理內存充足時設為 10-20(減少 Swap 使用),內存緊張時設為 50-60。
2. 臨時調整 swappiness(重啟后失效)
echo 10 > /proc/sys/vm/swappiness
3. 永久調整 swappiness(重啟生效)
編輯 /etc/sysctl.conf
文件,添加或修改以下行:
vim /etc/sysctl.conf
# 添加:
vm.swappiness = 10# 生效配置
sysctl -p
場景4:長期優化(避免內存不足反復出現)
-
升級物理內存(根本方案):
若系統長期available
內存低于 20%,且高內存進程是業務必需(如大數據服務、多虛擬機),建議增加物理內存(如從 32GB 升級到 64GB),這是最徹底的解決方式。 -
優化應用配置(減少不必要的內存占用):
- 對于 Java 應用:調整 JVM 參數(
-Xms
初始堆、-Xmx
最大堆),避免堆內存設太大導致浪費(例如 32GB 內存的機器,-Xmx
建議不超過 16GB); - 對于數據庫(MySQL/MongoDB):緩存參數(如
innodb_buffer_pool_size
)建議設為物理內存的 40%-50%(避免獨占過多內存); - 對于Web服務(Nginx/Apache):限制并發進程/線程數(如 Nginx 的
worker_processes
設為 CPU 核心數,避免過多進程占用內存)。
- 對于 Java 應用:調整 JVM 參數(
-
清理無用進程/服務:
檢查系統中是否有長期閑置的服務(如postfix
、telnet
、無用的監控插件),停止并禁用其開機啟動:# 查看開機啟動服務 systemctl list-unit-files --type=service | grep enabled# 停止并禁用無用服務(例如禁用 postfix) systemctl stop postfix systemctl disable postfix
-
監控內存變化(提前預警):
用nmon
、glances
或prometheus + grafana
搭建內存監控,當available
內存低于 10% 時觸發告警,避免內存耗盡導致進程崩潰。
三、注意事項
- 不要盲目關閉緩存:
buff/cache
是 Linux 提升磁盤性能的關鍵,手動釋放后若系統再次讀寫磁盤,緩存會重新增長(屬于正常現象),無需頻繁釋放; - 謹慎使用 kill -9:強制殺死進程可能導致數據丟失(如未保存的數據庫事務),優先嘗試優雅停止(如
kill 進程PID
或服務管理命令); - Swap 并非越多越好:交換分區過大(如超過物理內存 2 倍)會導致系統過度依賴磁盤,反而降低性能,建議根據實際內存需求設置(一般為物理內存的 1-1.5 倍)。
通過以上步驟,可先臨時釋放緩存緩解內存壓力,再定位高內存進程并優化配置,最終結合長期監控和硬件升級,徹底解決 Linux 內存不足問題。