Визначення Memory overcommit в гостьовій віртуальній машині

При адмініструванні гостьових ВМ, запущених на хостах віртуалізації (будь то VMWare ESXi або Hyper-V), при аналізі проблем з продуктивністю досить часто доводиться стикається з ситуаціями, коли кількість доступної пам'яті ОС виявляється набагато менше, ніж бачить (призначено) операційна система. Наприклад, віртуальній машині виділено 8 Гб пам'яті, диспетчер задач показує вільним 1 Гб пам'яті, при це сумарне споживання пам'яті всіма запущеними процесами не перевищує 3 Гб. Куди поділися залишилися 4 Гб?

Як правило, причиною такої поведінки є використання в гіпервізора функції memory overcommit.

Memory overcommit (Визначення російською я не знаю, нехай буде оверкомміт пам'яті) це фіча гипервизора, яка дозволяє виділити віртуальним машинам пам'яті більше, ніж є на фізичному хості, однак без гарантії того, що в конкретний момент часу вся запитана пам'ять може бути виділена. Як правило, overcommit дозволяє збільшити щільність розміщення віртуальних машин на хості за рахунок того, що пам'ять буде динамічно перерозподіляться між ними в залежності від поточного навантаження (ресурси ненавантажених / простоюють в даний момент ВМ можуть бути перерозподілені між більш завантаженими)

У VMWare одним їх механізмів реалізації memory overcommited є Memory Ballooning (Витіснення пам'яті, або якщо хочеться, обдурювання). У Hyper-V аналогічний функціонал реалізується функцією Dynamic Memory.

Примітка. До речі кажучи, і VMWare і Hyper-V для економії пам'яті і реалізації технології overcommit широко і досить ефективно використовуєте стиснення пам'яті.

У VMWare balloon реалізується за рахунок драйвера vmmemctl.sys (Входить в VMware Tools), який у разі потреби може захопити фізичну пам'ять, надувши всередині пам'яті фіктивний процес-куля (baloon). Таким чином зайнята пам'ять стає недоступна додаткам, а гипервизор може перерозподілити вивільнену пам'ять між іншими ВМ. У разі Hyper-V Dynamic memory використовується драйвер dmvsc.sys з комплекту служб інтеграції (компонент Dynamic Memory VSC). Налаштуваннями overcommit управляє адміністратор гипервизора.

А як же визначити зсередини ВМ, що їй реально доступно менше фізичної пам'яті, ніж те, яке бачить операційна система?

Розглянемо, як визначити наявність і розмір balloon драйвера в гостьовій ОС Windows. Отже, розберемо таку ситуацію:

ВМ з гостьової Windows Server 2012 R2 виділено 8 Гб оперативної пам'яті. Диспетчер завдань показує, що пам'ять використовується на 93% (7,4 Гб пам'яті зайнято). Однак, якщо скласти кількість пам'яті, яке використовують всі запущені процеси, можна прийти до несподіваного висновку - реально використовується тільки 2,5 Гб. Куди ж поділися 5 Гб пам'яті? Ні Task Manager, ні Resource Monitor відповіді на це питання не дадуть.

Щоб зрозуміти, що відбувається з пам'яттю, потрібно скористатися утилітою RamMap Марка Русиновича (в одних з минулих кейсів я показував, як використовувати цю утиліту для діагностики проблеми з системним кешем файлової системи). Качаємо утиліту з сайту Microsoft (https://technet.microsoft.com/en-us/library/ff700229.aspx) і запускаємо з правами адміністратора. Після цього, на вкладці Use Counts бачимо, що велика частина пам'яті (5,4 Гб) використовується об'єктом Driver Locked.

Це і є та пам'ять, яку "з'їв" гипервизор і перерозподілив іншим віртуальним машинам через balloon-драйвер в гостьовій ОС. Тобто на хості гипервизора не вистачає пам'яті, або адміністратор гипервизора примусово "зарізав" ресурси для даної ВМ.

Поточний розклад по пам'яті в ВМ на Hyper-V можуть дати лічильники окремі продуктивності в Performance Monitor:

  • Hyper-V Dynamic Memory -> Guest Visible Memory
  • Hyper-V Dynamic Memory -> Physical Memory

Щоб відключити таку поведінку, адміністратор гипервизора повинен відключити в налаштуваннях ВМ Hyper-V опцію Enable Dynamic Memory (або збільшити значення мінімальної резервації).

Якщо використовується хост VMWare ESXi - можна в налаштуваннях виділення ресурсів (Resource Settings) Зарезервувати для даної машини більше пам'яті, або відразу зарезервувати всю пам'ять - Reserve all guest memory (All locked).