You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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交换。

结合你的系统数据,当时的问题可以拆解成这几个关键点:

  1. MemAvailable不是绝对可用内存:它是系统估算的、能立即分配给新进程的内存,会排除共享内存、被锁定的缓存页(比如你这里Mlocked的59MB)等无法快速回收的部分。当时你的shared内存有5GB,这部分大多是VM间共享资源或tmpfs,很难被释放,导致实际可快速调用的内存远低于总空闲值。
  2. QEMU的内存分配策略:默认情况下,KVM用MAP_PRIVATE+MAP_ANONYMOUS方式分配内存,这种方式要求系统有足够的空闲物理页,而不是依赖swap。如果没有swap,内核没法把当前占用的内存页换出去腾空间,自然拿不出足够的空闲页给新VM。
  3. 内存提交限制触发:看/proc/meminfo里的CommitLimit(无swap时等于物理内存)只有16GB左右,但Committed_AS已经接近20GB——这说明系统已经承诺了超过物理内存的内存分配,没有swap的话,新的内存申请直接会被内核拒绝。添加swap后,CommitLimit变成物理内存+swap的总和,系统就能接受更多内存承诺了。

你添加swap后系统恢复正常,正好验证了这点:swap的存在让内核可以把非活跃内存页换出到磁盘,腾出足够的空闲物理页给QEMU分配,同时也提升了内存提交上限,解决了分配失败的问题。

简单说,不是总内存不够,而是无swap时系统无法快速回收足够的空闲物理页,且内存提交已超限,导致QEMU的即时内存分配请求被内核拒绝。

备注:内容来源于stack exchange,提问作者LetMeSOThat4U

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 14:05:28