一、OOM报错(Out Of Memory)
原因
- 物理内存不足:系统物理内存耗尽
- 内存泄漏:应用程序持续占用内存不释放
- 配置不当:内存分配参数设置不合理
- 进程过多:同时运行过多内存密集型应用
解决方法
# 1. 查看内存使用情况
free -h
cat /proc/meminfo
# 2. 查看OOM killer日志
dmesg | grep -i "killed process"
journalctl | grep -i "out of memory"
# 3. 调整swappiness参数(降低对swap的依赖)
echo 10 > /proc/sys/vm/swappiness
# 或永久修改
echo 'vm.swappiness=10' >> /etc/sysctl.conf
# 4. 限制进程内存使用
# 使用cgroups或ulimit限制单个进程内存
# 5. 优化应用程序配置
# 调整Java应用的-Xmx、-Xms参数
# 调整数据库的内存配置
二、Swap分区
Swap分区的作用
- 当物理内存不足时,将不常用的内存页换出到磁盘
- 防止系统因内存不足而崩溃
- 提供虚拟内存扩展
Swap分区创建
方法1:使用文件创建Swap
# 1. 创建swap文件(这里创建4GB)
sudo dd if=/dev/zero of=/swapfile bs=1M count=4096
# 2. 设置正确的权限
sudo chmod 600 /swapfile
# 3. 格式化为swap
sudo mkswap /swapfile
# 4. 启用swap文件
sudo swapon /swapfile
# 5. 永久生效,添加到/etc/fstab
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
# 6. 验证
free -h
swapon --show
方法2:使用分区创建Swap
# 1. 创建分区(使用fdisk或parted)
sudo fdisk /dev/sdX
# 2. 格式化为swap
sudo mkswap /dev/sdXn
# 3. 启用swap分区
sudo swapon /dev/sdXn
# 4. 添加到/etc/fstab
echo '/dev/sdXn none swap sw 0 0' | sudo tee -a /etc/fstab
个人经验:SWAP安装maxKB时内存满导致终端卡住
问题描述:
在SWAP空间不足的情况下安装内存密集型软件(如maxKB),导致:
- 终端完全卡死,无响应
- 系统变得极其缓慢
- 无法执行任何命令
解决方法:
# 方法1:通过SSH连接(如果系统支持多用户登录)
ssh username@server_ip
# 方法2:使用Magic SysRq键(需要内核支持)
# 启用Magic SysRq
echo 1 > /proc/sys/kernel/sysrq
# 尝试安全重启(按顺序执行)
# Alt + SysRq + r : 切换键盘到原始模式
# Alt + SysRq + e : 发送TERM信号给所有进程
# Alt + SysRq + i : 发送KILL信号给所有进程
# Alt + SysRq + s : 同步文件系统
# Alt + SysRq + u : 重新挂载文件系统为只读
# Alt + SysRq + b : 立即重启
# 方法3:强制重启(最后手段)
# 按住电源键强制关机,然后重启
# 重启后的修复步骤:
# 1. 检查文件系统
sudo fsck -f /dev/sdXn
# 2. 增加swap空间
sudo fallocate -l 2G /swapfile2
sudo chmod 600 /swapfile2
sudo mkswap /swapfile2
sudo swapon /swapfile2
# 3. 监控内存使用
htop
watch -n 1 free -h
三、磁盘空间管理
磁盘满了 - 查找大文件
使用find命令
# 查找大于100MB的文件
find / -type f -size +100M 2>/dev/null
# 查找大于1GB的文件
find / -type f -size +1G 2>/dev/null
# 按大小排序显示前10个大文件
find / -type f -size +100M -exec ls -lh {} \; 2>/dev/null | awk '{ print $5 ": " $9 }' | sort -hr | head -10
使用du命令
# 查看当前目录各子目录大小
du -h --max-depth=1 | sort -hr
# 查看指定目录大小
du -sh /path/to/directory
# 查找最大的10个目录
du -ah / | sort -rh | head -10
# 交互式查看磁盘使用情况
ncdu /
inode满了 - 查找小文件
inode满的原因
- 大量小文件占用inode
- 文件系统inode数量有限
- 邮件系统、缓存系统容易产生大量小文件
查找方法
# 1. 检查inode使用情况
df -i
# 或
ls -i /path/to/file # 查看文件inode号
# 2. 查找包含大量文件的目录
# 统计目录中的文件数量
find /path/to/dir -type f | wc -l
# 3. 查找小文件(小于10KB)
find / -type f -size -10k 2>/dev/null | head -20
# 4. 按目录统计文件数量
find / -type d 2>/dev/null | while read dir; do
echo "$(find "$dir" -maxdepth 1 -type f 2>/dev/null | wc -l) $dir"
done | sort -rn | head -10
# 5. 查找空文件
find / -type f -empty 2>/dev/null
# 6. 查找临时文件
find /tmp /var/tmp -type f 2>/dev/null | wc -l
清理小文件策略
# 清理临时文件
sudo rm -rf /tmp/*
sudo rm -rf /var/tmp/*
# 清理日志文件
sudo journalctl --vacuum-size=100M # 保留最近100M日志
sudo find /var/log -name "*.log" -type f -mtime +30 -delete
# 清理包缓存
sudo apt-get clean # Debian/Ubuntu
sudo yum clean all # CentOS/RHEL
# 清理Docker资源(如果使用Docker)
docker system prune -a -f
四、文件被进程占用处理
问题现象
当文件被进程占用时,即使删除文件,磁盘空间也不会立即释放,直到占用进程结束。
解决方法
1. 查找被删除但仍被占用的文件
# 查看已删除但仍被进程占用的文件
lsof | grep deleted
# 查找特定文件的占用情况
lsof | grep filename
lsof /path/to/file
2. 处理被占用文件的完整流程
# 示例:处理被Apache占用的日志文件
# 1. 发现磁盘空间不足
df -h
# 2. 查找大文件但发现已被"删除"
du -sh /* 2>/dev/null | sort -hr
# 3. 查找被删除但仍被占用的文件
lsof | grep deleted
# 输出示例:
# apache2 1234 www-data 1w REG 8,1 2.1G 123456 /var/log/apache2/access.log (deleted)
# 4. 确认占用进程
ps aux | grep 1234
# 5. 安全释放空间的方法:
# 方法A:重启相关服务(推荐)
sudo systemctl restart apache2
# 方法B:清空文件内容(如果必须保持服务运行)
sudo truncate -s 0 /proc/1234/fd/1
# 方法C:发送信号让进程重新打开日志文件
sudo kill -USR1 1234
# 方法D:强制终止进程(最后手段)
sudo kill -9 1234
3. 预防措施
# 使用logrotate管理日志文件
sudo vim /etc/logrotate.d/custom
# 示例配置:
/var/log/myapp/*.log {
daily
missingok
rotate 7
compress
delaycompress
notifempty
copytruncate # 重要:复制后截断,避免文件被占用
dateext
}
# 定期检查文件占用情况
#!/bin/bash
# 监控脚本示例
lsof | grep deleted | awk '{print $2, $9}' | sort -u | while read pid file; do
echo "PID $pid 正在占用已删除文件: $file"
echo "进程信息: $(ps -p $pid -o comm=)"
done
实用脚本:磁盘空间监控
#!/bin/bash
# disk_monitor.sh
# 监控磁盘使用率
THRESHOLD=80
CURRENT_USAGE=$(df / | awk 'NR==2 {print $5}' | sed 's/%//')
if [ $CURRENT_USAGE -gt $THRESHOLD ]; then
echo "警告: 根分区使用率 ${CURRENT_USAGE}% 超过阈值 ${THRESHOLD}%"
# 查找大文件
echo "前10大文件:"
find / -type f -size +100M -exec ls -lh {} \; 2>/dev/null | head -10
# 检查inode
echo -e "\nInode使用情况:"
df -i /
fi
# 检查被删除但仍被占用的文件
DELETED_FILES=$(lsof | grep deleted | wc -l)
if [ $DELETED_FILES -gt 0 ]; then
echo -e "\n发现 $DELETED_FILES 个被删除但仍被占用的文件"
lsof | grep deleted | head -5
fi
总结
磁盘管理是Linux系统维护的重要环节,需要定期:
- 监控磁盘使用率和inode使用情况
- 及时清理不必要的文件
- 合理配置swap空间
- 处理被进程占用的文件
- 建立预防机制,避免磁盘空间问题影响系统运行
Comments NOTHING