Короткий ответ
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 не отдают balloon | Integration Services |
Возможные причины
- Maximum = 64 ГБ у десяти гостей на хосте 128 ГБ, ночной backup/индексация съели demand.
- Minimum/Startup слишком высокие, хост не может забрать balloon.
- DM включён у СУБД, которая не отдаёт память.
- IC memory (balloon) не работает в госте.
- NUMA/Static при этом ещё и Overside.
- Сумма 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, PriorityResource metering (если включено):
Enable-VMResourceMetering -VMName 'VM-APP01'
Measure-VM -Name 'VM-APP01' | Format-List VMName, AvgRAM, MinRAM, MaxRAM, TotalDiskSmart 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. Включите, подождите интервал.