Linux 服务器内存监控与优化指南
一、查看内存使用情况
1. 基础命令
bash
# 查看内存使用情况(最常用)
free -h
# 查看详细内存信息
free -m # 以 MB 为单位显示
free -g # 以 GB 为单位显示
free -s 5 # 每 5 秒刷新一次
# 持续监控内存(每 2 秒刷新一次)
watch -n 2 free -h
输出说明:
total: 总内存used: 已使用内存(包括 buffers 和 cache)free: 完全空闲的内存shared: 共享内存(通常用于 tmpfs)buff/cache: 缓存和缓冲区占用的内存available: 可用内存(free + 可释放的缓存)
2. 查看进程内存占用
bash
# 查看所有进程内存占用(按内存使用排序)
ps aux --sort=-%mem | head -20
# 查看特定用户进程
ps aux -u username --sort=-%mem
# 查看内存占用百分比最高的进程
ps aux | awk '{print $2, $4, $11}' | sort -k2 -rn | head -10
# 使用 top 命令(按内存排序:先按 Shift + M)
top
# 或者使用 htop(更直观)
htop
# 查看特定进程的详细内存信息
pmap -x <PID>
cat /proc/<PID>/status | grep -i vm
# 查看进程的 VSS 和 RSS
ps aux | awk '{print $2, $5, $6, $11}' | head -20
# 第 5 列:VSZ (虚拟内存大小 KB)
# 第 6 列:RSS (物理内存大小 KB)
3. 查看系统内存详情
bash
# 查看详细内存统计信息
cat /proc/meminfo
# 查看关键内存指标
cat /proc/meminfo | grep -E "MemTotal|MemFree|MemAvailable|Buffers|Cached|SwapTotal|SwapFree"
# 查看内存使用趋势(每 1 秒输出一次,共 10 次)
vmstat 1 10
# 查看内存使用统计(需要安装 sysstat)
# 安装:yum install sysstat 或 apt-get install sysstat
sar -r 1 10 # 每 1 秒输出一次,共 10 次
sar -r # 查看今天的历史数据
# 查看内存使用历史
sar -r -s 10:00:00 -e 18:00:00
# 查看系统负载和内存
iostat -x 1 5
4. 实时监控工具
bash
# 使用 atop(需要安装)
# 安装:yum install atop 或 apt-get install atop
atop
# 使用 nmon(需要安装)
# 安装:yum install nmon 或 apt-get install nmon
nmon
# 使用 glances(需要安装)
# 安装:pip install glances 或 yum install glances
glances
二、内存占用过高的原因分析
1. 系统层面常见原因
- 缓存占用过多:Linux 会使用未使用的内存作为文件系统缓存(buff/cache)
- 多个进程占用内存:多个应用程序同时运行
- 内存泄漏:某个进程持续占用内存不释放
- Swap 空间不足或未配置:物理内存不足时无法使用 Swap
- 内存碎片:长期运行导致内存碎片化
2. 如何判断内存是否真的不足
bash
# 查看 available 内存(这是关键指标)
free -h
# available = free + 可释放的缓存
# 如果 available 很小,说明内存紧张
# 如果 available 正常,但 used 很大,通常是缓存占用,这是正常的
三、降低内存占用的方法
1. 清理系统缓存(谨慎使用)
bash
# 查看当前缓存
free -h
# 同步数据到磁盘(重要:先执行 sync)
sync
# 清理页面缓存(不影响应用程序)
sudo sh -c 'echo 1 > /proc/sys/vm/drop_caches' # 清理页面缓存
sudo sh -c 'echo 2 > /proc/sys/vm/drop_caches' # 清理目录项和 inode
sudo sh -c 'echo 3 > /proc/sys/vm/drop_caches' # 清理所有缓存
# 注意:
# 1. 生产环境谨慎使用,可能导致 I/O 性能短暂下降
# 2. 缓存会在需要时自动释放,通常不需要手动清理
# 3. 清理后,系统会重新加载缓存,短期内可能影响性能
2. 配置 Swap 空间
创建 Swap 文件(推荐)
bash
# 1. 创建 Swap 文件(推荐大小为物理内存的 1-2 倍,但不超过 4GB)
sudo fallocate -l 4G /swapfile
# 或者使用 dd 命令(如果 fallocate 不支持)
# sudo dd if=/dev/zero of=/swapfile bs=1G count=4
# 2. 设置权限(只有 root 可以读写)
sudo chmod 600 /swapfile
# 3. 格式化为 Swap
sudo mkswap /swapfile
# 4. 启用 Swap
sudo swapon /swapfile
# 5. 验证
free -h
swapon --show
# 6. 永久启用(添加到 /etc/fstab)
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
# 7. 验证 fstab 配置
sudo mount -a
调整 Swap 使用倾向
bash
# 查看当前 swappiness 值(默认通常是 60)
cat /proc/sys/vm/swappiness
# 临时调整(值越小,越倾向于使用物理内存)
# 0-100:0 表示尽量不使用 Swap,100 表示积极使用 Swap
sudo sysctl vm.swappiness=10
# 永久调整(添加到 /etc/sysctl.conf)
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
# 建议值:
# - 物理内存充足:10-30
# - 物理内存紧张:60(默认)
# - 数据库服务器:1-10
删除 Swap 文件(如果需要)
bash
# 1. 禁用 Swap
sudo swapoff /swapfile
# 2. 从 /etc/fstab 中删除对应行
sudo sed -i '/swapfile/d' /etc/fstab
# 3. 删除文件
sudo rm /swapfile
3. 优化系统参数
bash
# 编辑 /etc/sysctl.conf
sudo vi /etc/sysctl.conf
# 添加以下配置
vm.swappiness=10 # 减少 Swap 使用倾向
vm.vfs_cache_pressure=50 # 控制内核回收用于缓存目录和 inode 的内存(默认 100)
vm.dirty_ratio=15 # 系统内存中脏页的最大百分比(默认 20)
vm.dirty_background_ratio=5 # 后台写入脏页的最大百分比(默认 10)
vm.overcommit_memory=0 # 内存分配策略(0=启发式,1=总是允许,2=不允许过度分配)
vm.overcommit_ratio=50 # 允许过度分配的内存百分比(默认 50)
# 应用配置
sudo sysctl -p
4. 查找并终止占用内存的进程
bash
# 1. 找出占用内存最大的进程
ps aux --sort=-%mem | head -10
# 2. 查看进程详细信息
ps -p <PID> -o pid,ppid,cmd,%mem,%cpu,rss,vsz
# 3. 如果确定可以终止,使用 kill 命令
kill <PID> # 正常终止
kill -9 <PID> # 强制终止(谨慎使用)
# 4. 批量终止同类进程
pkill -f "process_name"
pkill -u username # 终止某个用户的所有进程
5. 限制进程内存使用
使用 systemd 限制服务内存
bash
# 编辑服务文件
sudo systemctl edit your-service.service
# 添加以下内容
[Service]
MemoryMax=2G # 最大内存限制
MemoryHigh=1.5G # 软限制(超过后开始限制)
MemoryLimit=2G # 硬限制(等同于 MemoryMax)
# 重新加载配置
sudo systemctl daemon-reload
sudo systemctl restart your-service.service
# 查看限制
systemctl show your-service.service | grep Memory
使用 cgroup 限制内存
bash
# 创建 cgroup
sudo mkdir /sys/fs/cgroup/memory/mygroup
echo 2G | sudo tee /sys/fs/cgroup/memory/mygroup/memory.limit_in_bytes
# 将进程添加到 cgroup
echo <PID> | sudo tee /sys/fs/cgroup/memory/mygroup/cgroup.procs
# 查看内存使用
cat /sys/fs/cgroup/memory/mygroup/memory.usage_in_bytes
6. 处理内存泄漏
查找内存泄漏进程
bash
# 1. 监控进程内存增长
watch -n 1 'ps aux --sort=-%mem | head -10'
# 2. 持续监控特定进程的内存使用
watch -n 1 'ps -p <PID> -o pid,rss,vsz,%mem'
# 3. 如果进程内存持续增长,可能是内存泄漏
使用 valgrind 检测(需要安装)
bash
# 安装
sudo yum install valgrind # CentOS/RHEL
sudo apt-get install valgrind # Ubuntu/Debian
# 检测内存泄漏
valgrind --leak-check=full --show-leak-kinds=all your-program
7. 清理不需要的文件和服务
bash
# 1. 查找大文件
find / -type f -size +100M 2>/dev/null
# 2. 查找占用空间最大的目录
du -sh /* 2>/dev/null | sort -hr | head -10
du -sh /var/* 2>/dev/null | sort -hr | head -10
# 3. 清理日志文件
# 查看日志文件大小
du -sh /var/log/*
# 清理旧日志(保留最近 7 天)
find /var/log -type f -mtime +7 -delete
# 4. 清理包管理器缓存
# CentOS/RHEL
sudo yum clean all
# Ubuntu/Debian
sudo apt-get clean
sudo apt-get autoclean
# 5. 清理临时文件
sudo rm -rf /tmp/*
sudo rm -rf /var/tmp/*
# 6. 清理系统不需要的包
# CentOS/RHEL
sudo yum autoremove
# Ubuntu/Debian
sudo apt-get autoremove
四、应急处理
1. 内存不足时的紧急处理步骤
bash
# 1. 查看当前内存状态
free -h
# 2. 找出占用内存最大的进程
ps aux --sort=-%mem | head -10
# 3. 检查是否有 OOM Killer 的活动
dmesg | grep -i "out of memory"
dmesg | grep -i "killed process"
# 4. 清理系统缓存(临时措施)
sync
sudo sh -c 'echo 3 > /proc/sys/vm/drop_caches'
# 5. 如果 Swap 未启用,启用 Swap
sudo swapon -a
# 6. 终止占用内存过大的非关键进程
kill <PID>
# 7. 如果应用有内存泄漏,考虑重启
2. 设置 OOM Killer 优先级
bash
# 查看进程的 OOM 分数
cat /proc/<PID>/oom_score
# 调整进程 OOM 优先级(值越小越不容易被杀死)
# -1000 到 1000:负数表示不容易被杀死,正数表示容易被杀死
echo -100 > /proc/<PID>/oom_score_adj
# 永久设置(在启动脚本中)
echo -100 > /proc/self/oom_score_adj
3. 监控内存使用并告警
bash
# 创建监控脚本
cat > /usr/local/bin/check_memory.sh << 'EOF'
#!/bin/bash
THRESHOLD=80
MEM_USAGE=$(free | grep Mem | awk '{printf "%.0f", $3/$2 * 100.0}')
if [ $MEM_USAGE -gt $THRESHOLD ]; then
echo "警告: 内存使用率 ${MEM_USAGE}% 超过阈值 ${THRESHOLD}%"
# 发送邮件或通知
# mail -s "内存告警" admin@example.com <<< "内存使用率: ${MEM_USAGE}%"
fi
EOF
chmod +x /usr/local/bin/check_memory.sh
# 添加到 crontab(每 5 分钟检查一次)
(crontab -l 2>/dev/null; echo "*/5 * * * * /usr/local/bin/check_memory.sh") | crontab -
五、内存优化最佳实践
-
定期监控内存使用
- 设置监控告警
- 使用
sar记录历史数据 - 定期检查内存使用趋势
-
合理配置 Swap
- 即使物理内存充足,也建议配置少量 Swap
- Swap 大小建议为物理内存的 1-2 倍
- 设置合理的 swappiness 值
-
优化系统参数
- 根据服务器用途调整 vm 参数
- 数据库服务器:降低 swappiness
- Web 服务器:可以适当提高 swappiness
-
及时处理内存泄漏
- 定期检查进程内存增长
- 使用工具检测内存泄漏
- 及时修复或重启有问题的进程
-
清理不需要的资源
- 定期清理日志文件
- 清理临时文件
- 卸载不需要的软件包
-
使用资源限制
- 对关键服务设置内存限制
- 使用 systemd 或 cgroup 限制资源使用
六、常用命令速查表
bash
# 查看内存
free -h # 查看内存使用
cat /proc/meminfo # 查看详细内存信息
vmstat 1 10 # 查看内存和系统状态
sar -r 1 10 # 查看内存统计
# 查看进程
ps aux --sort=-%mem | head -10 # 按内存排序显示进程
top # 交互式进程查看
htop # 更友好的进程查看工具
pmap -x <PID> # 查看进程内存映射
# 监控
watch -n 2 free -h # 持续监控内存
watch -n 1 'ps aux --sort=-%mem | head -10' # 持续监控进程
# 清理缓存
sync && sudo sh -c 'echo 3 > /proc/sys/vm/drop_caches'
# Swap 管理
swapon --show # 查看 Swap
sudo swapon /swapfile # 启用 Swap
sudo swapoff /swapfile # 禁用 Swap
# 系统参数
cat /proc/sys/vm/swappiness # 查看 swappiness
sudo sysctl vm.swappiness=10 # 设置 swappiness
sudo sysctl -p # 应用所有 sysctl 配置
七、内存问题排查流程
1. 查看内存使用情况
└─> free -h
└─> 如果 available 很小 → 内存紧张
2. 找出占用内存的进程
└─> ps aux --sort=-%mem | head -10
└─> 检查是否有异常进程
3. 分析进程内存使用
└─> 监控进程内存增长
└─> 如果持续增长 → 可能是内存泄漏
4. 检查系统配置
└─> 是否配置 Swap
└─> swappiness 是否合理
└─> 系统参数是否优化
5. 采取优化措施
└─> 配置 Swap
└─> 优化系统参数
└─> 清理缓存(临时)
└─> 终止异常进程
└─> 重启有问题的服务
八、注意事项
- 不要随意清理缓存:Linux 的缓存机制是正常的,会自动释放
- 谨慎使用 kill -9:可能导致数据丢失
- 生产环境操作前备份:修改系统参数前先备份配置
- 监控告警要合理:避免误报,设置合理的阈值
- Swap 不是万能药:Swap 速度慢,应该优化应用而不是依赖 Swap