监控面板上一个"缺陷",客户报过来了:他看任务管理器内存用了 42%,而我们面板显示 0%。

第一时间,我以为是采集坏了。这功能是我们新加的,读 Hyper-V 宿主机侧的 VM 内存。0% 和 42% 差太远,不是"采样误差",是"这条路可能根本走不通"。

我先用最直接的命令查:

Get-VM | % { "$($_.Name) 动态=$(.Get-VMMemory).DynamicMemoryEnabled 需求=$($_.MemoryDemand)" }

一列出来,规律像印刷一样整齐:

动态内存开的 VM,内存需求(Memory Demand)都有值;动态内存没开的 VM,需求全是 0。

那台客户报的 42% 的,正是"动态内存没开"的——需求恒为 0,占 0%。

我有点不甘心,把宿主机侧能想到的数据源全部试了一遍:Hyper-V 性能计数器(Hyper-V Dynamic Memory VM 类别)、Hyper-V VM Vid Partition 的 Physical Pages Allocated、WMI SummaryInformation 全字段……

结果:

性能计数器那个类别,只有开启动态内存的 VM 才有实例,固定内存的根本没有。
Vid Partition 的 Physical Pages Allocated,是"当前分配了多少物理页",固定内存 VM 就是满配,永远不变,不含使用量。
SummaryInformation 的 MemoryUsage 也是分配值;MemoryAvailable 根本不是客户机可用内存,口径对不上。

到这里我确认了技术边界:

Hyper-V 只在"动态内存"模式下,才收客户机内部的反馈(所以动态内存 VM 有内存需求值)。固定内存的客户机,从不向宿主机报告内存用量。宿主机侧,对固定内存的 VM,无论怎么查,都拿不到"任务管理器那个 42%"。这不是实现的 bug,是架构。

跟客户解释也简单:你任务管理器那个数,是客户机内部自己算的;云厂商的监控也是一样的——精确的内存使用率,都得装在客户机里的 agent 上报,宿主机层给不了。AWS、Azure、阿里云,没装 agent 的 Windows 机器,云监控里就没有精确内存这一项,只有宿主机层能看到的 CPU/网络/磁盘。

结局:这类 VM 的内存监控,面板先老实显示成"未开启动态内存,暂无数据"——不造假,不误导。哪天它在维护窗口转成动态内存(Min/Max 锁当前额度,行为不变),内存监控就有了。

这笔的教训:

1. 宿主机侧能看到什么,边界要清楚。不是"命令没试对",是那块数据,架构上就不存在。
2. 监控数值为 0,可能是"真 0",也可能是"根本读不到"。如果 0 得那么整齐、那么规律,大概率是后者——警惕。
3. 跟客户解释技术边界,诚实比硬造一个"看起来准"的数,更不容易翻车。