服务器交换内容占用过大问题 快速解决
bash
服务器交换内容占用过大问题:看起来可以解决 命令行、独写卡顿问题
第一步:调低 swappiness(告诉系统:优先用物理内存)
sysctl vm.swappiness=1
第二步:重启 Swap 分区
swapoff -a && swapon -a
第三步:禁止虚拟机内存被交换到硬盘
vi /etc/libvirt/qemu.conf 新增:memory_lock = 1
1465 cp qemu.conf qemu.conf_2026_1102
1466 vi qemu.conf
1467 systemctl restart libvirtd
一键把这 8.7G 数据"逼"回物理内存
线索二:坏消息,元凶找到了------那个 8.7G 的 QEMU 虚拟机
看你跑出来的进程占用表,排名第一的元凶是:
PID 1206914 (qemu-system-x86): 8710732 kB in swap <-- 约 8.7GB
这刚好对应了你的总 swap 空间(8GB = 8388344 kB)。也就是说,你这台服务器 100% 的 swap 空间,全被这一个 QEMU 虚拟机吃掉了。
为什么没在换页了,用起来还是很卡?
因为 Linux 的内存管理非常"懒"。这 8.7GB 的 QEMU 内存数据现在被冷冰冰地存在了硬盘(Swap 分区)里。
虽然你物理内存还有 130G 空闲,但 Linux 不会自动把这些数据搬回物理内存。这导致:
只要这个虚拟机有任何读写、网络包或后台调度,CPU 就必须发起"缺页中断",去硬盘里把这 8.7G 的数据一点点捞回来,单次读取延迟极高,表现为时不时卡一下。
你的 CPU 运行队列(r 列)在 11~18 之间跳动,说明有多个进程在排队等 CPU 和 I/O 资源。
终极解法:一键把这 8.7G 数据"逼"回物理内存
你现在已经是 root 身份了,直接在终端执行以下三步。由于你物理内存有 130G 空闲,这个过程非常安全,不会 OOM(内存溢出):
第一步:调低 swappiness(告诉系统:死也优先用物理内存)
sysctl vm.swappiness=1
第二步:重启 Swap 分区(核心步骤,会把硬盘里的数据全部搬回物理内存)
swapoff -a && swapon -a
注意:执行这一步时,系统需要把这 8.7G 数据从硬盘读回内存,这期间终端可能会卡顿 10 到 30 秒,这是完全正常的物理 I/O 过程,千万不要强制断开连接,耐心等待它恢复即可。
第三步:验证物理内存和 Swap 状态
free -h
执行完后,再看一眼 Swap 行的 used,应该已经变成了 0B 或者一个极小的数字。
以后怎么防止它再发生?(针对 QEMU/KVM)
既然这台机器专门跑 QEMU 虚拟机,最好的办法是禁止虚拟机内存被交换到硬盘。
你可以修改 libvirt 的全局配置文件:
nano /etc/libvirt/qemu.conf
找到 memory_lock = 0 这一行,去掉前面的 #,改为:
memory_lock = 1
保存退出后,重启 libvirtd 服务:
systemctl restart libvirtd
这样以后所有的 QEMU 虚拟机内存都会锁定在物理内存中,再也不会进 swap 导致卡顿了。
查看当前正在运行的虚机命令
最常用的是这个:
virsh list
它只会列出当前正在运行的虚拟机,显示它们的 ID、名称、状态。
如果想看所有(包括关机、暂停的):
virsh list --all
如果你想对照刚才找出来的那个吃 Swap 最凶的进程(PID 1206914),可以用这个命令反查它叫什么名字:
ps -o user,pid,cmd -p 1206914
需要我把释放 swap、锁定内存以及查看虚拟机的这几个常用命令,帮你整合成一段直接能跑的排查脚本吗?