Windows каже, що оперативна пам'ять закінчилася, поки є ще 4 Гб фізичної пам'яті


24

Скріншот системної інформації з Process Explorer

Ця системна інформація отримана від Process Explorer. Є ще фізична пам'ять, але в системі майже немає пам'яті.

Диспетчер завдань також показує, що використовується близько 74% загальної оперативної пам’яті.

З моменту встановлення Windows 8.1 комп'ютер мав 4 + 8 = 12 ГБ оперативної пам’яті. Я оновив його, змінивши 4 Гб на 8 ГБ модуль. Чи може це бути проблемою? Або така поведінка нормальна, і я просто неправильно зрозумів значення наявної фізичної пам'яті?


Зображення, яке він намагався долучити, знаходиться тут: tinypic.com/view.php?pic=npon5c&s=8#.Va3P3_lVhBc Я схвалив редагування, щоб додати цю URL-адресу, але це, мабуть, недостатньо.
Джеймі Ханрахан

@JamieHanrahan: зображення слід завантажувати за допомогою Ctrl+Gярлика, щоб обмін стеками міг уникнути їх гниття з часом.
Делтік

@Deltik Завантажувати це було не моє зображення.
Джеймі Ханрахан

@JamieHanrahan - Після того, як питання було подано, матеріалу було надано ліцензію, на цей момент зображенням є громади.
Ramhound

Помічена для подальшої довідки, дякую. Я просто побачив посилання на сайт типічного типу в запропонованій редакції, і схвалив це редагування, але це не мало ефекту.
Джеймі Ханрахан

Відповіді:


65

Коротка відповідь

Спливаюче вікно "поза пам'яттю" говорить про те, що у вас закінчується ліміт приватної пам'яті - тип віртуальної пам'яті. Не те, щоб у вас залишилася оперативна пам'ять (фізична пам'ять). Не має значення, скільки у вас є оперативної пам’яті. Наявність великої кількості доступної оперативної пам’яті не дозволяє перевищити ліміт фіксації. Ліміт фіксації - це сума загальної оперативної пам’яті (використовується чи ні!) Плюс поточний розмір файлу сторінки.

І навпаки, те, що "використовує" ліміт фіксації (який здебільшого створює віртуальний адресний простір-процес), не обов'язково використовує будь-яку ОЗУ! Але ОС не дозволить створити її, якщо вона не знатиме, що є якесь місце для її зберігання, якщо це коли-небудь доведеться. Таким чином, ви можете зіткнутися з лімітом фіксації, не використовуючи всю свою оперативну пам’ять або навіть більшу частину оперативної пам'яті.

Ось чому не слід працювати без файлу сторінки. Зауважте, що файл сторінки насправді ніколи не може бути записаний на! Але це все одно дозволить вам уникнути помилок "з низьким рівнем пам'яті" та "поза пам'яттю".

Проміжний відповідь

Насправді Windows не має повідомлення про помилку для закінчення оперативної пам’яті. Чого у вас не вистачає, це "обмежити ліміт".

Графік "Системний" у цій версії Провідника провідників названий погано. Це повинно бути позначено як "здійснити плату". (У моїй версії це називається "Системна фіксація". Краще, але все ще не повністю послідовно.) У будь-якому випадку "поточна" висота графіка є тим, що показано нижче в текстовому розділі як "Зробити зарядку" - " Поточний ", а максимальна висота графіка представляє" Зняти заряд "-" Обмеження ".

"Здійснення плати" позначає віртуальний адресний простір, який підтримується файлом сторінки (якщо у вас є) - іншими словами, якщо він не може вміститися в оперативній пам'яті, решта йде у файл сторінки. (Є й інші типи vas, які підкріплені іншими файлами - це називається "mapped" vas - або вони повинні залишатися в оперативній пам'яті весь час; останній називається "nonpageable".) "Ліміт фіксації" - це максимум, що "стягнути плату" може бути. Він дорівнює розміру оперативної пам’яті плюс розмір файлу сторінки.

У вас, мабуть, немає файлу сторінки (я можу сказати, оскільки ваш ліміт фіксації дорівнює вашому розміру оперативної пам’яті), тому ліміт фіксації - це просто розмір оперативної пам’яті.

Мабуть, різні програми + ОС використовували майже всі максимально можливі зобов’язання.

Це не має нічого спільного з тим, наскільки оперативна пам'ять є вільною або доступною. Так, у вас є близько 4,5 ГБ оперативної пам’яті. Це не означає, що ви можете перевищити ліміт зобов’язань. Виділена пам'ять не обов'язково використовує оперативну пам'ять і не обмежується обсягом доступної оперативної пам'яті.

Вам потрібно або ввімкнути повторно файл сторінки - використовуючи це дуже докладно, я б запропонував файл з 16 Гб сторінки, тому що ви не хочете змушувати ОС зберігати стільки цих речей в оперативній пам’яті, а файл сторінки найкраще працює, якщо він має багато вільного місця - а то й додати більше оперативної пам’яті. Набагато більше. Для гарної продуктивності вам потрібно мати достатньо місця в оперативній пам’яті для коду та інших речей, які не підкріплені файлом сторінки (але можуть бути підписані на інші файли).

Дуже довга відповідь

(але все ж набагато коротший, ніж глава управління пам’яттю Windows Internals ...)

Припустимо, що програма виділяє 100 Мб процесорно-приватної віртуальної пам'яті. Це робиться за допомогою виклику VirtualAlloc з опцією "зробити". Це призведе до збільшення на 100 Мб "Збір коштів". Але це "виділення" насправді не використовує жодної ОЗУ! Оперативна пам’ять використовується лише тоді, коли вперше доступ до цього новозазначеного віртуального адресного простору .

Як зрештою використовується оперативна пам'ять

(якщо це коли-небудь стане)

Перший доступ до щойно створеного простору майже завжди буде записом пам'яті (читання новопризначеної приватної вази перед її написанням майже завжди є помилкою програмування, оскільки її початковий вміст, суворо кажучи, не визначений). Але читайте чи пишіть, результат - перший раз, коли ви торкаєтесь сторінки щойно виділеної вази, - це помилка сторінки . Хоча слово "помилка" звучить погано, помилки сторінки - це цілком очікувана і навіть необхідна подія в ОС віртуальної пам'яті.

У відповідь на цей тип помилок сторінки, пейджер (частина диспетчера оперативної пам'яті ОС, яку я іноді скорочую як "Mm"):

  1. виділити фізичну сторінку оперативної пам’яті (в ідеалі зі списку нульових сторінок, але в будь-якому випадку вона виходить із того, що Windows називає «доступним»: списком нульових, вільних або резервних сторінок у такому порядку уподобань);
  2. заповнити запис таблиці сторінки, щоб пов’язати фізичну сторінку з віртуальною; і, нарешті
  3. відхилити виняток помилок сторінки.

Після цього код, який зробив посилання на пам'ять, знову виконає інструкцію, що призвела до помилки сторінки, і цього разу посилання буде успішною.

Ми говоримо, що сторінка була "зібрана" в робочий набір процесів і в оперативну пам'ять. У диспетчері завдань це буде відображатися як збільшення на одній сторінці "приватного робочого набору" процесу на 4 сторінки. І зменшення на одну сторінку наявної фізичної пам'яті. (Останнє може бути важко помітити на зайнятій машині.)

Примітка 1: Помилка цієї сторінки не передбачала нічого, прочитаного з диска. Ніколи раніше доступна сторінка закріпленої віртуальної пам'яті не починає життя на диску; він не має місця на диску , щоб прочитати його з . Він просто "матеріалізується" на раніше доступній сторінці оперативної пам'яті. Статистично, фактично більшість помилок сторінки вирішуються в оперативній пам’яті, або на спільних сторінках, які вже є в ОЗП для інших процесів, або в кешах сторінок - в режимі очікування або модифікованих списках, або як «вимагають нуля» сторінки, як ця.

Примітка 2. Це займає лише одну сторінку, 4096 байт, з "Доступно". Ніколи не зачіпається раніше закріплений адресний простір, як правило, реалізовується - виправдано - лише одна сторінка за часом, оскільки кожна сторінка "торкається" вперше. Не було б жодних поліпшень, жодної переваги в тому, щоб робити більше за один раз; це зайняло б лише n разів. Навпаки, коли сторінки доводиться читати з диска, намагається деяка кількість «читати голову», оскільки переважна більшість часу на читанні диска відбувається накладні витрати, а не фактична передача даних. Сума "допущена" залишається на рівні 100 МБ; той факт, що одна або сторінки були винні, не зменшує стягнення плати.

Примітка 3:Припустимо, що у нас є 4 ГБ "доступної" оперативної пам'яті. Це означає, що ми могли посилатися на вже виділену, але ніколи раніше згадувану пам'ять, приблизно мільйон разів (4 ГБ / 4096) до того, як ми не залишимось оперативної пам'яті. Після цього, якщо у нас є файл сторінки, як задумали Девід Катлер та Лу Перазцолі, деякі з найдавніших посилань сторінки в оперативній пам’яті будуть збережені на диску та надані доступними для використання для усунення цих останніх помилок сторінки. (Насправді ОС би ініціювала методи рекультивації оперативної пам’яті, такі як «обробка робочого набору», а до цього фактичні записи у файл сторінки кешуються та відображаються в модифікованому списку сторінок для ефективності, і ...) Ніщо з цього не вплине на "скоєний" кол. Це, однак, стосується "межі здійснення". Якщо немає місця для всіх "

І це продовжується ...

Але припустимо, що ми не зробили на мільйон більше посилань, а ще є "доступні" сторінки близько 4 Гб. Тепер припустимо, що той самий процес - чи інший, не має значення - робить інший VirtualAlloc, на цей раз, скажімо, 200 Мб. Знову ж таки, до 200 Мб додається плата за фіксацію, і це не вилучає жодної оперативної пам’яті з доступної. Просто VirtualAlloc'ating адресний простір не використовує відповідну кількість оперативної пам’яті, а наявність низької «доступної» оперативної пам’яті не обмежує обсяг адресного простору, який ви можете VirtualAlloc (а також не має великої доступної оперативної пам’яті).

(Ну гаразд ... є невеликий накладний обсяг, який становить одну (сторінкову!) Сторінку, яка використовується для таблиці сторінок на кожні 2 МБ (4 МБ, якщо ви користуєтеся системою x86, не PAE) виділено віртуальний адресний простір, і існує "дескриптор віртуальної адреси" з декількох десятків байт для кожного практично суміжного виділеного діапазону.)

Таким чином можливо - і звичайне! - використовувати багато "фіксації заряду", використовуючи лише невеликий об'єм оперативної пам'яті.

Отже, якщо "фіксація" віртуального адресного простору не використовує оперативну пам'ять, чому має бути обмеження?

Тому що "плата за фіксацію" справді представляє потенційне використання місця для зберігання в майбутньому . "Ліміт фіксації" являє собою загальну кількість пам’яті (RAM + простір сторінок), доступного для розміщення таких виділень, якщо вони коли-небудь дійсно посилаються і звідти їх потрібно зберігати десь.

Коли Mm схвалить запит VirtualAlloc, обіцяє - "взяти на себе зобов'язання" - всі наступні доступу до пам'яті до виділеної області будуть успішними; вони можуть призвести до помилок сторінки, але всі помилки зможуть бути усунені, оскільки Є достатній об'єм пам’яті для зберігання вмісту всіх цих сторінок, будь то в ОЗУ чи у файлі сторінки. Mm це знає, тому що знає, скільки є місця для зберігання (ліміт фіксації) та скільки вже було "скоєно" (поточне стягнення комісії).

(Але до всіх цих сторінок ще не обов'язково доступно, тому не обов'язково в будь-який момент має бути фактичний обсяг пам’яті.

Отже ... А як щодо "система поза пам'яттю"?

Якщо ви спробуєте VirtualAlloc, а поточна плата за фіксацію плюс потрібний розмір розподілу перевищить обмеження, і ОС не зможе розширити файл сторінки так, щоб збільшити ліміт фіксації ... у вас з'явиться спливаюче вікно "пам'яті" вгору, і процес бачить виклик VirtualAlloc FAIL. Більшість програм просто закине руки і помре в цей момент. Деякі будуть сліпо натискати, припускаючи, що виклик вдався, і пізніше не вдасться, коли вони намагаються посилатися на регіон, який вони вважали виділеним.

Знову (вибачте за повторення): не важливо, скільки у вас доступної оперативної пам’яті. ОС пообіцяла, що оперативна пам’ять або простір файлів сторінок будуть доступні, коли це буде потрібно, але ця обіцянка не віднімається від "Доступно". Наявна оперативна пам’ять використовується лише скоєним vm, коли на неї вперше посилається , що є причиною того, що вона "помиляється" ... тобто реалізується у фізичній пам'яті. І просто здійснення (= виділення) віртуальної пам'яті цього не робить. Він займає лише вільний віртуальний адресний простір і робить з нього корисний віртуальний адресний простір.

Але в «з пам'яті» випадку був запит виділення для виділеної пам'яті, і ОС додав ток фіксацію заряду до розміру цього neew запиту ... і виявив , що загальна сума становить понад ніж зробити межа. Тож якби ОС затвердила цю нову, і на весь цей простір було посилається після цього, не було б жодного реального місця (RAM + filefile), щоб зберігати все це.

ОС не дозволить цього зробити. Це не дозволить виділити більше суди, ніж у неї є простір, щоб утримати її в гіршому випадку - навіть якщо все це буде "винне". У цьому полягає мета "обмеження на здійснення".

Я кажу вам три рази, я кажу вам три рази, я кажу вам три рази: Обсяг оперативної пам'яті "Доступний" не має значення. Те, що введений віртуальний простір фактично ще не використовує весь цей простір для зберігання, не має значення. Windows не може "скористатися" віртуальним виділенням, якщо в майбутньому це не може бути винне.

Зауважте, існує ще один тип вази, який називається "mapped", в основному використовується для коду та доступу до великих файлів даних, однак він не стягується "фіксацією плати" і не обмежується "обмеженням на здійснення". Це відбувається тому, що він має власну область зберігання, файли, які "нанесені на нього". Єдине обмеження для "картографічної" вази - це кількість дискового простору, яке ви маєте для картографічних файлів, та кількість вільної ваги у вашому процесі для їх відображення.

Але коли я дивлюся на систему, я ще не зовсім на межі виконання?

Це в основному проблема вимірювання та зберігання записів. Ви переглядаєте систему після того, як виклик VirtualAlloc вже був випробуваний і не вдався.

Припустимо, у вас залишилось лише 500 Мб ліміту фіксації, а якась програма намагалася зробити VirtualAlloc 600 Мб. Спроба не вдається. Потім ви дивитесь на систему і кажете: "Що? Залишилося ще 500 МБ!" Насправді до цього часу може залишитися набагато більше, тому що процес, про який йде мова, до цього моменту повністю пішов, тому ВСЕ його раніше виділеної закріпленої пам'яті було випущено.

Проблема полягає в тому, що ви не можете озирнутися назад у часі і побачити, якою була плата за вчинення в момент спроби алокації. І ви також не знаєте, скільки місця було для спроби. Таким чином, ви не можете остаточно зрозуміти, чому спроба не вдалася, або наскільки більше "ліміту фіксації" знадобилося б, щоб вона могла працювати.

Я бачив, що "система втрачає пам'ять". Що це?

Якщо у вищенаведеному випадку ОС МОЖНА розширити файл сторінки (тобто ви залишите його за замовчуванням у налаштуваннях "керована системою", або ви керуєте ним, але ви встановите максимум, більший за початковий, І достатньо вільного місця на диску), і таке розширення збільшує ліміт фіксації достатньо, щоб виклик VirtualAlloc мав успіх, тоді ... Mm розширює файл сторінки, і виклик VirtualAlloc вдається.

І ось тоді, коли ви бачите "система працює НИЗКО на пам'яті". Це раннє попередження, що якщо все триватиметься без пом'якшення, швидше за все, ви побачите попередження "поза пам'яттю". Час закрити деякі програми. Я б почав із вікон вашого браузера.

І ти думаєш, що це добре? Розширення сторінок - це зло !!!

Ні, це не так. Дивіться, ОС насправді не "розширює" існуючий файл. Це просто виділяє нову міру. Ефект схожий на будь-який інший непомітний файл. Старий вміст файлу сторінки залишається там, де вони є; їх не потрібно копіювати на нове місце чи щось подібне. Оскільки більшість вхідних файлів сторінки в порівняно з розмірами файлу сторінки є порівняно невеликими, шанси на те, що будь-який переданий перехід буде перетинати межу, є досить рідкісними, тому фрагментація не зашкодить сильно, якщо це не дуже.

Нарешті, як тільки всі процеси, які "зайняли" простір у розширенні, припиняються (при відключенні ОС, якщо не швидше), розширення будуть мовчки звільнені, а файл сторінки повернеться до попереднього розміру та розподілу - якщо він був суміжним раніше, він знову так.

Таким чином, дозволити розширення файлів сторінок діє як абсолютно безкоштовна мережа безпеки: якщо ви це дозволите, але система ніколи не потребує, система не буде "постійно розширюватись і скорочувати файл сторінки", як це часто заявляється, тому нічого не коштуватиме . І якщо вам це коли-небудь знадобиться, це позбавить вас від програм, що збиваються з помилками "поза віртуальної пам'яті".

Але, але ...

Я читав на десятках веб-сайтів, що якщо ви дозволите розширення файлів сторінок, Windows буде постійно розширюватися та скорочувати файл сторінки, і що це призведе до фрагментації файлу сторінок, поки не дефрагментуєте його.

Вони просто помиляються.

Якщо ви ніколи не бачили спливаючого вікна «дефіцит пам’яті» (або, у старих версіях, «дефіцит віртуальної пам’яті»), ОС ніколи не розширював файл вашої сторінки.

Якщо ви бачите це спливаюче вікно, то це говорить про те, що ваш початковий розмір файлу сторінки занадто малий. (Мені подобається встановити приблизно в 4 рази максимальне спостережуване використання; тобто лічильник парфмонів "% піку користування сторінками" повинен бути менше 25%. Причина: Простір сторінок керується, як і будь-яка інша купа, і найкраще працює з великою кількістю вільного простору грати.)

Але чому б вони просто ...

Можна стверджувати, що ОС повинна просто дозволити розподілу відбуватися, а потім дозволити відмовитись від посилань, якщо немає оперативної пам’яті для вирішення помилок сторінки. Іншими словами, вище, де ми описали, як працює помилка початкової сторінки, що робити, якщо "виділити доступну фізичну сторінку оперативної пам'яті" (крок 1) не вдасться зробити, тому що не було доступної, і не було місця залишилося на сторінці що-небудь зробити, щоб зробити будь-яке доступне?

Тоді пейджер не зможе усунути помилку сторінки. Потрібно було б дозволити повідомлення про виняток (помилка сторінки) назад до несправного потоку, ймовірно, зміненого на якийсь інший код виключення.

Філософія дизайну полягає в тому, що VirtualAlloc поверне нуль (технічно - покажчик NULL) замість адреси, якщо у вас закінчується ліміт фіксації, і цілком розумно очікувати, що програміст знає, що виклик VirtualAlloc може вийти з ладу. Тож очікується, що програмісти перевірять цю справу і роблять щось відповідне у відповідь (наприклад, дають вам можливість зберегти свою роботу до цього моменту, а потім закінчити програму «витончено»). (Програмісти: Ви перевіряєте, чи не повертається покажчик NULL з malloc, new тощо.

Але програмістам не слід очікувати, що така проста посилання на пам'ять, як

i = 0;             // initialize loop counter

може вийти з ладу - ні, якщо він знаходиться в регіоні успішно виділеного адресного простору. (Або, натомість, накреслений адресний простір.) Але саме це може статися, якщо філософія "дозволити перерозподілений розподіл, нехай посилання на пам'ять вийде з ладу".

На жаль, посилання на пам'ять, як та у рядку коду вище, просто не має зручного способу повернення поганого стану! Вони просто повинні працювати , подібно до додавання і віднімання. Єдиний спосіб повідомити про такі невдачі - це виключення. Отже, щоб обробити їх, програмісту доведеться перетворити всю програму на обробку винятків. (спробуйте ... зловити і все таке.)

Це можна зробити ... Але оброблювачеві було б важко знати, як "зробити правильно" у відповідь на ці винятки, оскільки в коді було б так багато, багато пунктів, де вони могли виникнути. (Зокрема, вони можуть виникати при кожному посиланні на пам'ять до пам'яті VirtualAlloc'd, до пам'яті, виділеної malloc чи new ..., а також до всіх локальних змінних, оскільки стек також є VirtualAlloc'd.)

Коротше кажучи, зробити випуск програми вишукано в цих випадках було б дуже важко.

З іншого боку, досить легко перевірити повернення покажчика NULL з VirtualAlloc (або malloc або new, з цього приводу, хоча вони не зовсім однакові), а потім зробити щось розумне ... як не намагатися йти і робити все, що це було для програми, необхідної для цього віртуального простору. І, можливо, запитайте користувача, чи хочуть вони зберегти свою роботу поки що, якщо вони є. (Зрозуміло, занадто багато додатків не заважають робити це навіть багато.)

Інші користувачі комітів

Між іншим, "ліміт фіксації" не зменшується різними асигнуваннями ОС, такими як підказка та пул без підключення, список PFN тощо; їм просто доручається здійснити стягнення, як це відбувається. Також розмір плати за фіксацію або обмеження фіксації не впливає на розмір "вікна" оперативної пам'яті відео, або навіть на розмір "вікна" оперативної пам'яті відео.

Перевірте це самостійно

Ви можете продемонструвати все це за допомогою інструменту testlimit із сайту SysInternals. Варіант -m виділить виділений адресний простір, але не буде "торкатися" до нього, тому не спричинить розподіл оперативної пам'яті. Тоді як опція -d буде виділяти, а також посилатись на сторінки, що призводить до того, що збір плати збільшиться, а наявна оперативна пам’ять зменшиться.

Список літератури

Windows Internals Русинович, Соломон та Іонеску. Існують навіть демонстрації, які дозволяють довести всі ці моменти за допомогою інструменту testlimit. Однак, я мушу вас попередити, що якщо ви вважаєте, що це було давно, попередити: лише глава Мм на 200 сторінках; вище - НАДАГО спрощена версія. (Будь ласка, перегляньте розділ "Подяки" у Вступі.)

Дивіться також документацію MSDN VirtualAlloc


4
@AcePL Я пояснив, чому. Коротше кажучи: це відбувається тому, що обмеження на його здійснення занадто низьке для його навантаження. Ліміт фіксації - загальний розмір ОЗУ + поточний розмір файлу сторінки. Об'єм "доступної" оперативної пам'яті в неї не входить. Механізм "обмеження ліміту" не дозволить виділити віртуальний адресний простір поза наявністю фізичного сховища (оперативна пам'ять + резервне зберігання на диску, тобто файл сторінки), щоб зберегти цей матеріал. Пам’ятайте, навіть якщо це віртуально, його потрібно зберігати десь після того, як його вперше винили.
Джеймі Ханрахан

5
@AcePL - користувачеві насправді не вистачає пам'яті. У нього не вистачає віртуальної пам’яті. Це пояснення є 100% дійсним.
Рамхаунд

1
@Rahul Basu Насправді я б очікував, що короткий коментар буде набагато складніше зрозуміти. ;) Це та багато подібних питань є свідченням того, що багато людей мають глибокі помилки щодо віртуальної пам’яті, адресних просторів, робочих наборів і т. Д. Не їх вина - це дуже складна тема, а дисплеї MS ніколи не були настільки чіткими, як вони могли бути. . Але потрібно багато слів, щоб пояснити навіть частину цього. У Windows Internals є діаграми, які допомагають. Анімовані діаграми були б ще кращими ...
Джеймі Ханрахан

3
Можливо, що представляє інтерес: "просто нехай розподіл відбудеться, а потім нехай посилання виходять з ладу, якщо немає оперативної пам’яті для усунення помилок сторінки" схоже на те, що Linux робить за замовчуванням: це дозволяє певну кількість перевиконання, але в якийсь момент це " У віртуальної пам’яті не вистачає брудних сторінок, і тоді вбивця поза пам’яті забиває… і вбиває те, що може бути абсолютно не пов’язаним із цим процесом . Так, противно.
Боб

1
@JamieHanrahan Схоже, ви вже робили (вибачте, трохи зайняті). Так, перевиконання налаштовується, і деякі дистрибутиви відключать його. Але схоже, що це все ще було поширеним у 2013 та 2014 роках , і я вважаю, що це ядро ​​за замовчуванням, коли воно не встановлено явно (по distro або користувачеві).
Боб
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.