Короткий ответ

Dynamic Memory отдаёт гостю RAM между Minimum и Maximum по demand. Сумма Maximum на HV01 легко больше физической памяти: это нормально пока demand не взлетел у всех сразу. Нехватка — смотрите MemoryDemand/MemoryStatus, не «выключить половину VM». Снижение Maximum часто возможно на лету; изменение Startup/Minimum может потребовать Off — планируйте окно, не делайте Turn Off из паники.

SQL, Exchange, Java heap, часть Linux — плохие кандидаты на агрессивный DM. Им лучше статическая RAM.

Симптомы и как отличить

Типичная картина:

  • Task Manager хоста: мало Available, высокий Committed;
  • Get-VM : MemoryAssigned << MemoryDemand, Status про память;
  • файл Smart Paging на CSV растёт, диск стонет;
  • после старта ещё одной VM остальные просели.

Отличия:

Что видноКуда
Не стартует из-за RAMстарт VM
Медленный диск из-за pagingдиск VM, perf
Хост в целом боленhealth
IC не отдают balloonIntegration Services

Возможные причины

  1. Maximum = 64 ГБ у десяти гостей на хосте 128 ГБ, ночной backup/индексация съели demand.
  2. Minimum/Startup слишком высокие, хост не может забрать balloon.
  3. DM включён у СУБД, которая не отдаёт память.
  4. IC memory (balloon) не работает в госте.
  5. NUMA/Static при этом ещё и Overside.
  6. Сумма Startup при одновременном cold boot после падения стойки.

Диагностика

Get-VMHost | Format-List MemoryCapacity, LogicalProcessorCount
Get-VM | Format-Table Name, State, @{N='AssignedMB';E={[int]($_.MemoryAssigned/1MB)}}, @{N='DemandMB';E={[int]($_.MemoryDemand/1MB)}}, MemoryStatus, DynamicMemoryEnabled
Get-VMMemory -VMName 'VM-APP01' | Format-List DynamicMemoryEnabled, Startup, Minimum, Maximum, Buffer, Priority

Resource metering (если включено):

Enable-VMResourceMetering -VMName 'VM-APP01'
Measure-VM -Name 'VM-APP01' | Format-List VMName, AvgRAM, MinRAM, MaxRAM, TotalDisk

Smart paging path и место:

Get-VM -Name 'VM-APP01' | Format-List SmartPagingFileInUse, SmartPagingFilePath
Get-ChildItem (Get-VM -Name 'VM-APP01').SmartPagingFilePath -ErrorAction SilentlyContinue

В госте: Task Manager / Get-Counter '\Memory\Available MBytes'. Если гость «ест» и не освобождает — это приложение, не Hyper-V «не даёт».

Журнал Worker: not enough memory, 0x800705AA.

Решение

Сценарий A. Завышен Maximum, гость отдаёт balloon

На лету часто можно:

Set-VMMemory -VMName 'VM-APP01' -MaximumBytes 16GB -Buffer 20
Get-VMMemory -VMName 'VM-APP01'

Проверьте, что Assigned падает у спокойных VM и растёт Available хоста. Priority (вес) повысьте критичным гостям, понизьте тестам.

Сценарий B. Нужно снизить Startup/Minimum

Многие параметры требуют Off:

# окно простоя
Stop-VM -Name 'VM-APP01'
Set-VMMemory -VMName 'VM-APP01' -DynamicMemoryEnabled $true -StartupBytes 4GB -MinimumBytes 2GB -MaximumBytes 12GB
Start-VM -Name 'VM-APP01'

Не ставьте Minimum = Maximum «чтобы как static» через DM — лучше -DynamicMemoryEnabled $false и фиксированный Startup.

Сценарий C. СУБД / приложения с locked memory

Выключите DM, назначьте статическую RAM по паспорту вендора. В SQL ограничьте max server memory так, чтобы оставался запас гостевой ОС.

Сценарий D. IC balloon мёртв

В госте службы интеграции, в Hyper-V Integration Service Memory (если отображается в вашей версии как часть IC). Обновите IC. Без balloon Dynamic Memory не забирает страницы обратно.

Суммируйте Assigned, не Maximum, когда решаете «влезет ли ещё одна VM». Maximum — потолок жадности. Скрипт в заявку:

$vms = Get-VM | Where-Object State -eq 'Running'
[pscustomobject]@{
  AssignedGB = [math]::Round(($vms | Measure-Object MemoryAssigned -Sum).Sum/1GB,1)
  DemandGB   = [math]::Round(($vms | Measure-Object MemoryDemand -Sum).Sum/1GB,1)
  HostGB     = [math]::Round((Get-VMHost).MemoryCapacity/1GB,1)
}

Если Demand близок к HostGB — вы уже в зоне paging/отказа старта. Снижайте тесты, не прод-SQL.

Сценарий E. Smart Paging спасает старт и убивает диск

Не оставляйте прод на smart paging. Освободите RAM или не стартуйте лишние VM. Перенесите paging path с CSV прод-IO только как временный костыль.

Не включайте Dynamic Memory «чтобы влезло ещё пять VM» без замера Demand за неделю пика. Воскресный запас лжёт. Measure-VM по критичным гостям — в заявку до изменения лимитов. Гость без balloon (часть Linux/appliance) не отдаст RAM: для него Maximum не резерв, статика.

Как проверить, что проблема устранена

Get-VM | Format-Table Name, MemoryAssigned, MemoryDemand, MemoryStatus
Get-VMMemory -VMName 'VM-APP01'
Measure-VM -Name 'VM-APP01'

Хост Available стабилен, MemoryStatus OK, Smart Paging не in use. Гость без OOM, SLA приложения держится. После Live Migration на второй узел — те же лимиты не взрывают HV02.

Если не помогло

  • Хост всё равно пухнет: драйверы, file cache, не VM. Health хоста.
  • Linux-гость игнорирует hot-add: ядро/IC, иногда только static.
  • После снижения max приложение деградировало — верните лимит, добавьте RAM в хост или разъедьте VM.
  • Не стартует: сумма Startup > свободного, статья старта VM.

Профилактика

  • Бюджет: сумма типичного demand + запас, не сумма Maximum.
  • Алерт MemoryStatus и Available хоста.
  • DM выключен у СУБД по умолчанию в стандарте.
  • Не cold-boot все VM одновременно без staggered start.
  • Metering раз в неделю (Measure-VM).
  • Перед массовым стартом после падения стойки включите VM по приоритету, не все сразу: сумма Startup легко выше Available.
  • Не поднимайте Maximum «про запас 64 ГБ» на тестовых гостях того же HV01, где крутится VM-APP01.

FAQ

Startup vs Minimum vs Maximum?

Startup — сколько нужно чтобы вообще включить (и часто первый кусок). Minimum — ниже Hyper-V не отдаст при balloon. Maximum — потолок demand.

Можно ли менять RAM Generation 1 на лету?

Hot-add зависит от поколения и гостя. Dynamic Memory как раз для изменения assigned без reboot, в пределах min/max. Не путать с изменением vCPU.

Почему Demand выше Assigned?

Хост не даёт (давление, priority). Гость троттлится. Это и есть сигнал уменьшить соседей или добавить RAM.

Buffer 50% хорошо?

Обычно много. 20% типичный старт. 50% на десятке VM резервирует фиктивный запас.

Отключить Dynamic Memory «навсегда» всем?

Нет. Для VDI/файловиков с пиками — полезно. Для БД — часто вредно.

Measure-VM нули?

Resource metering не включён или сброшен Reset-VMResourceMetering. Включите, подождите интервал.