KVM启动虚拟机时出现'cannot set up guest memory'错误的原因咨询
KVM启动虚拟机时出现'cannot set up guest memory'错误的原因咨询
我在启动一台分配了1GB内存的虚拟机时遇到了内存分配问题,尽管系统本身有16GB内存:
error: Failed to start domain exampleVM error: internal error: qemu unexpectedly closed the monitor: 2023-09-10T11:49:20.853205Z qemu-system-x86_64: cannot set up guest memory 'pc.ram': Cannot allocate memory当前我已经有三台虚拟机在运行,总共分配了6GB内存。
当时我没有配置交换分区(现在已经添加了,系统能正常工作了),但为什么这会成为问题呢?系统难道不应该把内存中的页面交换出去来为虚拟机内存腾出空间吗?
请解释这个问题,这对我来说相当费解。谷歌搜索到的答案都不够明确,都是些猜测性的内容。
系统内存相关输出
free -g 输出:
total used free shared buff/cache available Mem: 15 6 2 5 7 3 Swap: 7 3 4
ps_mem.py 输出:
Private + Shared = RAM used Program 44.0 KiB + 82.0 KiB = 126.0 KiB dnsmasq 120.0 KiB + 79.0 KiB = 199.0 KiB xrdp 292.0 KiB + 81.0 KiB = 373.0 KiB cron 280.0 KiB + 115.0 KiB = 395.0 KiB agetty (2) 540.0 KiB + 100.5 KiB = 640.5 KiB auditd 600.0 KiB + 58.5 KiB = 658.5 KiB mdadm 868.0 KiB + 150.5 KiB = 1.0 MiB xrdp-sesman 996.0 KiB + 157.5 KiB = 1.1 MiB exim4 200.0 KiB + 1.0 MiB = 1.2 MiB ha_logd (2) 984.0 KiB + 333.5 KiB = 1.3 MiB systemd-timesyncd 1.2 MiB + 368.0 KiB = 1.5 MiB systemd-logind 1.0 MiB + 564.0 KiB = 1.5 MiB upowerd 1.6 MiB + 154.0 KiB = 1.7 MiB dbus-daemon 1.8 MiB + 154.0 KiB = 1.9 MiB smartd 1.5 MiB + 462.0 KiB = 1.9 MiB unattended-upgr 2.0 MiB + 94.5 KiB = 2.1 MiB systemd-udevd 1.6 MiB + 583.5 KiB = 2.2 MiB virtlogd 1.7 MiB + 559.5 KiB = 2.2 MiB polkitd 1.9 MiB + 314.0 KiB = 2.2 MiB systemd-journald 2.2 MiB + 126.5 KiB = 2.3 MiB rsyslogd 1.5 MiB + 854.5 KiB = 2.3 MiB ssh 1.4 MiB + 933.5 KiB = 2.4 MiB (sd-pam) 3.3 MiB + 617.5 KiB = 3.9 MiB udisksd 4.4 MiB + 1.2 MiB = 5.6 MiB tuned 4.2 MiB + 1.5 MiB = 5.7 MiB bash (2) 2.6 MiB + 3.5 MiB = 6.2 MiB sshd (3) 4.0 MiB + 3.2 MiB = 7.2 MiB systemd (2) 9.4 MiB + 1.2 MiB = 10.6 MiB libvirtd 13.6 MiB + 1.1 MiB = 14.7 MiB fail2ban-server 17.5 MiB + 300.5 KiB = 17.8 MiB zabbix_agent2 12.4 MiB + 40.5 MiB = 52.9 MiB heartbeat (6) 7.4 GiB + 6.2 MiB = 7.5 GiB qemu-system-x86_64 (5) --------------------------------- 7.6 GiB =================================
/proc/meminfo 输出:
MemTotal: 16298980 kB MemFree: 2471024 kB MemAvailable: 5498208 kB Buffers: 2161672 kB Cached: 3251996 kB SwapCached: 10692 kB Active: 8700828 kB Inactive: 4551496 kB Active(anon): 7763376 kB Inactive(anon): 2282256 kB Active(file): 937452 kB Inactive(file): 2269240 kB Unevictable: 59280 kB Mlocked: 59280 kB SwapTotal: 8388604 kB SwapFree: 2057932 kB Dirty: 0 kB Writeback: 0 kB AnonPages: 7888728 kB Mapped: 83356 kB Shmem: 2164944 kB Slab: 236904 kB SReclaimable: 144204 kB SUnreclaim: 92700 kB KernelStack: 4448 kB PageTables: 23336 kB NFS_Unstable: 0 kB Bounce: 0 kB WritebackTmp: 0 kB CommitLimit: 16538092 kB Committed_AS: 19768952 kB VmallocTotal: 34359738367 kB VmallocUsed: 0 kB VmallocChunk: 0 kB Percpu: 11904 kB HardwareCorrupted: 0 kB AnonHugePages: 7198720 kB ShmemHugePages: 0 kB ShmemPmdMapped: 0 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB Hugetlb: 0 kB DirectMap4k: 3027424 kB DirectMap2M: 13621248 kB
问题原因分析
咱们先从内存分配的核心逻辑说起,QEMU/KVM在启动虚拟机时,默认会尝试预分配连续的物理内存块(或者说,需要保证能立即拿到足够的可分配内存页),而不是依赖系统后续的swap交换。
结合你的系统数据,当时的问题可以拆解成这几个关键点:
MemAvailable不是绝对可用内存:它是系统估算的、能立即分配给新进程的内存,会排除共享内存、被锁定的缓存页(比如你这里Mlocked的59MB)等无法快速回收的部分。当时你的shared内存有5GB,这部分大多是VM间共享资源或tmpfs,很难被释放,导致实际可快速调用的内存远低于总空闲值。- QEMU的内存分配策略:默认情况下,KVM用
MAP_PRIVATE+MAP_ANONYMOUS方式分配内存,这种方式要求系统有足够的空闲物理页,而不是依赖swap。如果没有swap,内核没法把当前占用的内存页换出去腾空间,自然拿不出足够的空闲页给新VM。 - 内存提交限制触发:看
/proc/meminfo里的CommitLimit(无swap时等于物理内存)只有16GB左右,但Committed_AS已经接近20GB——这说明系统已经承诺了超过物理内存的内存分配,没有swap的话,新的内存申请直接会被内核拒绝。添加swap后,CommitLimit变成物理内存+swap的总和,系统就能接受更多内存承诺了。
你添加swap后系统恢复正常,正好验证了这点:swap的存在让内核可以把非活跃内存页换出到磁盘,腾出足够的空闲物理页给QEMU分配,同时也提升了内存提交上限,解决了分配失败的问题。
简单说,不是总内存不够,而是无swap时系统无法快速回收足够的空闲物理页,且内存提交已超限,导致QEMU的即时内存分配请求被内核拒绝。
备注:内容来源于stack exchange,提问作者LetMeSOThat4U
相关产品推荐
相关产品推荐

