必须先确认guest os已安装并启用气球驱动,否则virto_balloon完全不工作;需检查lsmod、lspci输出,加载virtio_balloon模块,libvirt xml中添加virtio memballoon设备,宿主机用virsh balloon/setmem触发,且guest需启用swappiness、足够memavailable及jvm容器支持等约束。

必须先确认 Guest OS 中已安装并启用了气球驱动,否则 virio_balloon 完全不会工作——这是 90% 的配置失败根源。
确认气球驱动是否加载
在虚拟机内部(Guest)执行以下命令检查模块是否就绪:
-
lsmod | grep balloon—— 应输出virtio_balloon -
lspci | grep -i balloon—— 应看到类似00:05.0 Unclassified device [00ff]: Red Hat, Inc. Virtio memory balloon - 若无输出,说明驱动未加载:运行
modprobe virtio_balloon并检查/proc/sys/vm/virtio_balloon是否存在(部分内核版本路径为/sys/devices/virtual/virtio-*/balloon/)
libvirt XML 中启用 ballooning 设备
KVM 虚拟机需显式声明气球设备,仅靠内核模块不够。编辑虚拟机定义(virsh edit vm-name),在 <devices></devices> 内添加:
<memballoon model="virtio"><address type="pci" domain="0x0000" bus="0x00" slot="0x05" function="0x0"></address> </memballoon>
- 务必确保
model='virtio',virtio-transitional或virtio-non-transitional也可用,但需与 Guest 内核版本兼容 - 若使用 Q35 机器类型,PCI 地址需避开保留槽位(如 slot=0x05 是安全默认值)
- 删除旧的
model='none'或注释掉的 memballoon 条目,否则 libvirt 可能忽略新配置
宿主机侧触发气球膨胀的实操方式
气球是否“膨胀”由宿主机上的 qemu-kvm 进程通过 virtio 控制寄存器通知 Guest,用户不能直接在 Guest 里调大 balloon;正确做法是:
- 在宿主机上执行:
virsh setmem vm-name --current 2048000(单位 KB,此处设为 2GB),即使当前分配值未变,也会触发气球驱动尝试回收闲置页 - 或更可控地使用:
virsh balloon vm-name 1536(单位 MB),该命令会直接向 Guest 的virtio_balloon设备写入目标内存大小,驱动据此申请/释放内存 - 观察效果:
virsh dommemstat vm-name查看actual(当前实际使用)、balloon(气球占用)、mem_swapped(是否发生 swap)等字段 - 注意:
balloon值上升 ≠ Guest 可用内存下降 —— 它只表示 Guest 主动归还了这么多页给 Host;真正影响业务的是actual是否稳定、pgmajfault是否突增(表明频繁缺页)
容易被忽略的关键约束
气球机制不是万能的,它依赖 Guest 内核的内存管理策略配合,几个硬性限制常被跳过:
- Guest 必须启用
swappiness(vm.swappiness > 0),否则当气球申请内存时,内核无法将不活跃页换出,会导致OOM killer杀进程而非收缩气球 - Guest 内存不能长期处于
MemAvailable 状态,否则气球一膨胀就触发 swap,延迟飙升;建议监控 <code>/proc/meminfo中的MemAvailable - 若 Guest 运行 Java 应用且 JVM 使用
-XX:+UseG1GC,需额外设置-XX:+UseContainerSupport(JDK 10+)并配-XX:MaxRAMPercentage,否则 JVM 不感知气球回收,仍按初始内存规划堆大小 - Windows Guest 需安装完整版
virtio-win驱动包,并在设备管理器中确认VirtIO Balloon Device状态为“正常”,其服务VirtioBalloon必须运行











