Архітектура пам'яті в Windows: міфи і легенди
Міф №1 : програма не може виділити більше пам'яті, ніж встановлено ОЗП
Міф походить від того, що люди не розуміють, що адресний простір програми тепер віртуальний. Він більше не пов'язаний з оперативною пам'яттю (ось вже більше п'ятнадцяти років).
Цей міф легко зруйнувати безпосереднім експериментом. Встановивши кількість ОЗП для віртуальної машини в 256 Мб, запустив її і виконав такий код: procedure TForm1.Button1Click(Sender: TObject); ,
begin
AllocMem(512 * 1024 * 1024); // выделить 512 Мб памяти
end;
Ця операція буде успішна (хоча і досить повільна ) . Операція була б миттєвою, якби ми використовували тільки резервування ( RESERVE ) , замість повноцінного виділення ( COMMIT ), але , можливо, тоді експеримент не був би таким видовищним.
Отже, ось знімок екрана із запущеною програмою до виділення:
і після натискаємо на кнопку двічі
і ось загальна статистика системи
Як ви бачите, на машині встановлено 261'616 КБ оперативної пам'яті. До виділення пам'яті наша програма займала 31'980 КБ віртуальної пам'яті і 3'764 КБ оперативної . Після виділення пам'яті програма стала займати 1'080'752 КБ віртуальної пам'яті і 1'748 КБ фізичної. Ви також можете побачити, що сумарна кількість виділеної пам'яті в системі дорівнює 1'313'300 Кб.
Як відомо , класичний сюжет Mythbusters складається з двох частин. Коли легенда зруйнована , руйнівники легенд підбирають такі умови, при яких відбувалося б подія, що згадується в легенді.
Цим ми зараз і займемося : ми заходимо у властивості системи і зменшуємо розмір файлу підкачки до 128 Мб. Таким чином, сумарний обсяг пам'яті , доступний системі і всім програмам , дорівнюватиме 256 + 128 = 384 Мб .
Перезавантаження , запускаємо тестовий приклад знову і ось результат:
На цей раз наш виклик AllocMem провалюється з викидом виключення EOutOfMemory . І Process Explorer показує нам причину:
Міф №2 : сумарний розмір пам'яті для всіх програм не може перевищувати 2 Гб
Вище ми побачили, що програма може виділити скільки завгодно пам'яті, поки у неї є місце у віртуальному адресному просторі. Тобто 32-х розрядна програма може виділити 512 Мб , але не 2 Гб - бо це розмір користувача частини адресного простору за замовчуванням. Деякі люди вважають, що всі запущені програми в системі не можуть виділити більше двох гігабайт пам'яті.
Цей міф походить від того, що люди не розуміють, що адресний простір програми тепер своє у кожної програми (ось вже більше п'ятнадцяти років). Подивимося , чи так це . Цього разу запустимо п'ять копій програми - прикладу з попереднього пункту і ось що вийде:
А ось і статус системи в цілому
Як бачите , ніяких проблем немає: всі запущені програми в системі змогли виділити 2'902'204 Кб пам'яті (і так, я підняв кількість ОЗП до 1 Гб, щоб система поменше гальмувала ) . Що стосується частини два , то вона виглядає так само, як раніше : не можна виділити пам'яті більше, ніж у вас є оперативної пам'яті + файлу підкачки .
Міф №3 : 32-х розрядна операційна система не може використовувати всі 4 Гб оперативної пам'яті
Максимальний для 32 -розрядних систем обсяг пам'яті - це 128 Гб , як зазначено в специфікації на Windows Server 2003 Datacenter Edition . Таке обмеження пов'язане з тим, що в більш потужних системах структури, застосовувані диспетчером пам'яті для відстеження фізичної пам'яті , споживали б занадто велику частину простору віртуальних адрес. Диспетчер пам'яті відстежує сторінки пам'яті за допомогою масиву , званого базою даних PFN , і з метою оптимізації продуктивності відображає весь вміст цієї бази у віртуальну пам'ять.
Так як кожна сторінка пам'яті представлена структурою даних обсягом 28 байт, в системі з фізичною пам'яттю ємністю 128 Гб для розміщення бази даних PFN потрібно 930 Мб. У 32-розрядних ОС Windows передбачено простір віртуальних адрес об'ємом 4 Гб, залежне від устаткування і за замовчуванням распределяемое між поточним процесом користувальницького режиму (наприклад, блокнотом) і системою. У таких умовах база даних PFN об'ємом 980 Мб займає майже половину з доступних 2 Гб системної частини простору віртуальних адрес, а значить, на відображення ядра, драйверів пристроїв, системного кеша і інших структур даних системи залишається всього 1 Гб:
З тієї ж причини в таблиці обмежень обсягу пам'яті вказані знижені ліміти при завантаженні в режимі / 3GB . Справа в тому, що для цього режиму характерна така схема поділу фізичної пам'яті , при якій процесам користувацького режиму дістається 3 Гб , а системі - всього 1 Гб. З метою підвищення продуктивності в ОС Windows Server 2008 для системних потреб резервується більш значуща частка адресного простору. Для цього максимальний обсяг фізичної пам'яті , підтримуваний в 32 -розрядних версіях ОС , скорочується до 64 Гб.
Але руйнівники легенд не були б руйнівниками легенд , якби вони вірили на слово. Тому вони повинні це перевірити. Беремо віртуальну машину , встановлюємо їй кількість ОЗУ в 4 Гб і запускаємо . Що ж ми бачимо ?
Щось не дуже схоже на обіцяні 128 Гб. У чому ж справа? Справа в тому , що обмеження в 128 Гб - це обмеження серверних ОС. Клієнтські ОС ( а Windows XP і Windows 7 - це клієнтські ОС) мають обмеження в 4 Гб. Ну , це нічого не пояснює. По-перше, чому така різниця ? Це маркетинговий хід ? По-друге : де ж наші обіцяні 4 Гб ? Ми бачимо всього 3.5 Гб
По-перше, в ході тестування Windows з'ясувалося , що якщо дозволити використання пам'яті більше 4 Гб , то багато систем аварійно завершують роботу , зависають і відмовляються завантажуватися. Відбувається це через те , що деякі драйвери пристроїв (особливо аудіо- і відеопристроїв ) запрограмовані на роботу з фізичними адресами в межах 4 Гб. Ці драйвери , виявляється, обрубують адреси понад 4 Гб, що призводить до пошкодження вмісту пам'яті з усіма витікаючими наслідками.
У серверних же системах, які, як правило, оснащуються менш специфічними пристроями з відносно простими і надійними драйверами, подібні проблеми виявлені не були. Виявлені недоліки екосистеми драйверів змусили стосовно клієнтським версіями ОС відмовитися від роботи з пам'яттю в обсязі понад 4 Гб, незважаючи на те, що теоретично її адресація можлива (звертаю увагу, що мова йде про фізичної пам'яті, а не про віртуальному адресному просторі, який навіть теоретично не може бути більше 4 Гб в 32-х розрядної системі).
По-друге , фактичний ліміт підтримки обсягу пам'яті нижче. Крім того, він залежить від набору мікросхем і характеристик підключених пристроїв. Справа в тому, що в таблицю фізичних адрес включається не тільки оперативна пам'ять, а й пам'ять пристроїв. При цьому , для сумісності з 32-розрядними операційними системами , які не здатні обробляти адреси понад 4 Гб, в системах x86 і x64 пам'ять пристроїв відображається нижче межі адресації 4 Гб.
Припустимо, що в системі встановлено 4 Гб оперативної пам'яті, а вікна в пам'ять мережевих адаптерів, аудіо- та відеопристроїв в сумі складають 500 Мб, тоді 500 Мб з 4 Гб оперативної пам'яті опиняться за кордоном адресації - і ми отримаємо доступні тільки 3.5 Гб фізичної пам'яті . Навіть якщо система оснащена всього 2 Гб фізичної пам'яті, може статися так, що частина її виявиться недоступною під керуванням 32-розрядної версії Windows. Причиною тому - набори мікросхем, практикуючі агресивне резервування областей пам'яті для пристроїв. Хоча такий сценарій, звичайно, досить рідкісний.