Proxmox 虚拟机占用内存高,需要先判断是:
- 虚拟机内部真的用了大量内存
- Proxmox 宿主机缓存占用
- KVM/QEMU 内存没有释放
- 内存气球(Ballooning)没有生效
- 某个 VM 内部服务异常(数据库、Java、K8s、Ceph 等)
下面按生产排查流程处理
1. 查看 Proxmox 宿主机整体内存
在 PVE 节点执行:
free -h
例如:
total used free
Mem: 256G 240G 5G
Swap: 32G 0G 32G
重点:
used高不一定异常- 看
available
如果:
available < 10%
说明真实内存压力
2. 查看哪个虚拟机占内存
方法1:PVE命令
qm list
查看:
VMID NAME MEM(MB)
100 k8s-node1 65536
101 gitlab 32768
102 mysql 32768
查看单个 VM
例如 VM 100:
qm status 100
查看详细:
qm config 100
例如:
memory: 65536
balloon: 1
3. 查看 QEMU 实际占用
宿主机:
ps aux | grep qemu
例如:
root 1234 300% qemu-system-x86_64 \
-id 100 \
-m 65536
查看:
ps -p 1234 -o pid,rss,vsz,cmd
RSS 是实际占用:
RSS 62000000 KB
约 60G
4. 查看虚拟机内部内存
进入 VM:
Linux
free -h
例如:
total used free
Mem: 64G 60G 1G
说明 VM 内部确实占满
继续:
top
或者:
htop
排序:
Shift + M
查看:
- java
- docker
- containerd
- postgres
- mysql
- elasticsearch
- kafka
- ceph
5. 常见大内存服务排查
Java
查看:
jps
或者:
ps aux | grep java
例如:
-Xmx32g
说明 JVM 最大32G
调整:
-Xms4g
-Xmx8g
Docker
查看:
docker stats
例如:
NAME MEM USAGE
mysql 20GB
elasticsearch 30GB
限制:
services:
mysql:
mem_limit: 8g
Kubernetes
查看:
kubectl top node
kubectl top pod -A
6. Proxmox Ballooning 内存回收
检查 VM:
qm config VMID
需要:
memory: 65536
balloon: 1
如果没有:
qm set 100 --balloon 1
虚拟机安装 balloon 驱动
Linux:
lsmod | grep balloon
应该看到:
virtio_balloon
没有:
modprobe virtio_balloon
永久:
echo virtio_balloon >> /etc/modules
7. Windows 虚拟机
安装:
virtio-win
检查:
设备管理器:
Memory Balloon Driver
否则 PVE 无法回收
8. 清理 Linux Cache(临时)
如果是 Linux VM:
查看:
free -h
例如:
buff/cache 100G
不是问题
如果必须释放:
sync
echo 3 > /proc/sys/vm/drop_caches
注意:
生产环境不建议长期使用
9. Proxmox 内存无法释放
常见:
QEMU残留
查看:
ps aux | grep qemu
重启 VM:
qm shutdown 100
qm start 100
如果无法:
qm stop 100
PVE服务重启
systemctl restart pvedaemon
systemctl restart pvestatd
10. 检查 NUMA(大内存服务器)
如果 VM >32G:
qm config 100
建议:
numa: 1
CPU:
cpu: host
否则可能:
- 内存访问慢
- 单节点压力高
11. 推荐生产配置
例如:
Kubernetes 节点 VM
memory: 128G
balloon: 0
numa: 1
cpu: host
K8s 节点通常关闭 balloon
普通业务 VM
memory: 32G
balloon: 1
如果是你之前的环境(PVE + K8s + GPU + Ceph),建议重点检查:
pveperf
free -h
qm list
ps aux | grep qemu
以及:
kubectl top node
kubectl top pod -A --sort-by=memory
如果方便,把下面输出贴出来:
free -h
qm list
ps aux | grep qemu
我可以帮你定位是哪台 VM 或哪个服务吃掉内存
proxmox显示虚拟机内存高,实际内部内存使用低
这种情况在 Proxmox(PVE)里很常见:
PVE 界面显示 VM 内存占用很高,但进入虚拟机内部
free -h/top看实际使用很低
通常不是虚拟机真的泄漏,而是 QEMU/KVM 分配给 VM 的内存没有被回收 。常见原因是 Ballooning 未启用、virtio-balloon 驱动未工作、Linux page cache、Windows 内存报告机制缺失
一、Linux系统
1. 先确认 PVE 显示的是什么
PVE Web:
VM → Summary → Memory usage
这里显示的是:
- QEMU 进程实际 RSS
- 或 balloon 后报告值
不是简单等价于:
free -h
里面的 used
2. 检查 VM 是否开启 Ballooning
宿主机:
qm config <VMID>
例如:
qm config 101
看:
memory: 65536
balloon: 1
如果没有:
balloon: 0
或者没有这一行:
启用:
qm set 101 --balloon 1
3. Linux 虚拟机检查 balloon 驱动
进入 VM:
lsmod | grep balloon
正常:
virtio_balloon
如果没有:
加载:
modprobe virtio_balloon
检查:
dmesg | grep balloon
应该类似:
virtio_balloon virtio0: initialized
永久加载:
echo virtio_balloon >> /etc/modules
4. 检查 VM 是否有 virtio balloon 设备
宿主机:
qm config <VMID>
应该有:
balloon: 1
如果是手工配置,也可以检查:
qm showcmd <VMID>
里面应该出现:
virtio-balloon-pci
5. Linux 内存缓存导致显示偏高
VM 内:
free -h
例如:
total used free
Mem: 64G 8G 2G
buff/cache: 54G
available: 55G
这种:
- 应用只用了 8G
- Linux 用大量 page cache
- PVE 可能认为 VM 使用较高
属于正常
查看:
cat /proc/meminfo | grep Cached
6. 手动触发 balloon 回收
进入 VM:
安装 balloon 工具:
Ubuntu/Debian
apt install qemu-guest-agent
启动:
systemctl enable qemu-guest-agent
systemctl start qemu-guest-agent
PVE:
VM → Options:
启用:
QEMU Guest Agent = Enabled
然后:
qm agent <VMID> ping
返回:
{}
说明正常
7. 查看 Balloon 当前状态
PVE:
qm monitor <VMID>
进入:
info balloon
例如:
balloon: actual=32768
表示当前实际给 VM 的内存
8. 如果是 Kubernetes 节点 VM
你的环境里有 K8s/GPU/Ceph,这类 VM 我通常建议:
关闭 balloon:
qm set <VMID> --balloon 0
原因:
Kubernetes 节点:
- kubelet
- containerd
- OSD
- GPU Operator
对内存稳定性要求高
推荐:
memory: 128G
balloon: 0
numa: 1
cpu: host
9. 如果是数据库 VM
例如:
- PostgreSQL
- MySQL
- Kafka
- Elasticsearch
也建议关闭 balloon
原因:
数据库会主动缓存:
例如:
MySQL buffer_pool 32G
OS cache 20G
PVE balloon 会影响性能
10. 最常见修复流程
假设 VMID=101:
# 开启 guest agent
qm set 101 --agent enabled=1
# 开启 balloon
qm set 101 --balloon 1
# 重启 VM
qm shutdown 101
qm start 101
进入 VM:
systemctl status qemu-guest-agent
lsmod | grep balloon
二、windows系统
PVE 显示 Windows VM 内存占用很高,但 Windows 任务管理器显示实际使用很低
最常见原因是:
- Windows 没安装 VirtIO Balloon Driver
- Ballooning 未启用
- QEMU Guest Agent 未安装/未运行
- Windows 文件缓存未及时释放
- PVE 显示的是 QEMU 分配内存,不是 Windows 应用实际占用
1. 检查 PVE VM 配置
宿主机执行:
qm config <VMID>
例如:
qm config 101
正常应该类似:
memory: 32768
balloon: 1
agent: 1
scsihw: virtio-scsi-single
bios: ovmf
machine: q35
如果没有:
开启 Balloon
qm set 101 --balloon 1
开启 Guest Agent
qm set 101 --agent enabled=1
2. Windows 安装 VirtIO Balloon 驱动(关键)
下载:
VirtIO-win ISO
挂载到 Windows:
PVE:
VM
└ Hardware
└ CD/DVD Drive
Mount VirtIO ISO
Windows 中打开:
D:\viostor
D:\Balloon
D:\guest-agent
安装 Balloon:
例如:
D:\Balloon\w11\amd64\blnsvr.exe
或者:
设备管理器:
Device Manager
└ System devices
└ VirtIO Balloon Driver
应该看到:
VirtIO Balloon Driver
没有黄色感叹号
3. 检查 Windows 服务
打开:
services.msc
确认:
QEMU Guest Agent
状态:
Running
Startup Type: Automatic
如果没有安装:
VirtIO ISO:
guest-agent\qemu-ga-x86_64.msi
安装
4. Windows 查看 Balloon 是否工作
PowerShell:
Get-Service balloon
或者:
sc query blnsvr
正常:
STATE : RUNNING
5. PVE 查看 Balloon 状态
宿主机:
qm monitor <VMID>
进入:
info balloon
例如:
balloon: actual=8192
如果你的 VM:
memory: 32768
但是:
actual=8192
说明 balloon 已回收
6. Windows 内存显示低,但 PVE 高的例子
例如:
PVE:
Memory usage:
28GB / 32GB
Windows:
任务管理器:
Memory 6GB / 32GB
原因:
Windows 已经申请过大量内存:
- 文件缓存
- SuperFetch
- DLL cache
- Hyper-V cache
- 应用退出后未立即归还
没有 balloon 时:
QEMU 仍占 32G
7. 手动释放 Windows 缓存(测试)
PowerShell:
管理员执行:
Clear-RecycleBin -Force
或者使用:
RAMMap
微软工具:
选择:
Empty
├ Empty Standby List
├ Empty System Working Set
然后观察 PVE
8. Windows VM 推荐生产配置
普通 Windows Server
例如:
Memory: 32G
Minimum memory: 8G
Ballooning: Enabled
QEMU Guest Agent: Enabled
数据库 / ERP / 大型应用 Windows
建议:
Memory: 64G
Ballooning: Disabled
QEMU Guest Agent: Enabled
例如:
- SQL Server
- Exchange
- SAP
- 大型 CAD
不要 balloon
9. 如果是 Windows Server 2019/2022 特别注意
需要:
- VirtIO-win 最新驱动
- QEMU Guest Agent
- Balloon driver
否则 PVE 永远看到:
100% Memory Used
PVE:
qm config <VMID>
Windows:
任务管理器 → 性能 → 内存:
或者 PowerShell:
systeminfo | findstr Memory
以及:
driverquery | findstr virtio
可以判断是不是 VirtIO Balloon 没安装