запобігти зависанню / безвідповідальності системи через заміну використання втеченої пам'яті


48

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

Отже, якщо процес продовжує розподіляти без обмежень, все стає безвідповідальним, поки цей процес не буде вбито вбивцею OOM. Мій ноутбук здається особливо розумним і реагує надзвичайно погано. Я щойно провів цілу годину, чекаючи завершення процесу, під час якого не можна було перемістити навіть курсор миші.

Як цього можна уникнути?

1) Вимкнути своп => Я часто запускаю багато процесів, які потім стають неактивними. Неактивні слід перемістити на своп.

2) Отримайте SSD => занадто дорого

3) встановити максимальну кількість пам'яті ulimit =>, але тоді вона виходить з ладу у випадках, коли програмі потрібен резонансний великий об'єм пам'яті. проблема полягає не в тому, що він використовує занадто багато, а в тому, що він пригнічує інші процеси

4) зберігайте важливі програми (X11, bash, kill, top, ...) у пам'яті і ніколи не змінюйте їх => чи можна це зробити? як? можливо, лише поміняти великі програми?

5)?


І ти повторився :( Почався gcc, поки працює Firefox, все було заблоковано на півгодини. Ні руху миші, ні читання електронних книг
BeniBela

Я не впевнений, що розумію, чого ти хочеш. Ви хочете, щоб система магічно робила справи швидше з наявними у неї ресурсами? Ви хочете, щоб він швидше вбивав процеси, які використовують багато пам'яті?
Девід Шварц

Схоже, що вам справді потрібно більше оперативної пам’яті. Або менш "неактивні" фонові завдання.
Даніель Б

2
Ви можете використовувати комбінацію клавіш Alt + SysRq + F, щоб змусити забій OOM-вбивці. Це може скоротити час, необхідний для того, щоб зачекати, поки ваша система відкриє консоль, щоб ви могли вбити процес.
hololeap

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

Відповіді:


45

TL; DR

Короткий тимчасовий / відповідь

  • Найпростіше : майте менший розділ для заміни і уникайте ядра, що намагається реалізувати брехню, що немає обмеження пам'яті, виконуючи процеси з повільного зберігання.
    • З великим свопом, OOM (менеджер пам'яті) не вживає заходів досить скоро. Як правило, він обліковується відповідно до віртуальної пам’яті, і, за моїм минулим досвідом, не вбивав речі, поки весь своп не заповнився, отже, система лущення та повзання ...
  • Вам потрібна велика заміна для сплячки?
    • Спроба / проблематика : встановіть деякі обмеження (наприклад, перевірити ulimit -v, а можливо встановити жорсткий або м'який межа, використовуючи asопцію в limits.conf). Раніше це працювало досить добре, але завдяки впровадженню WebKit gigacage, багато додатків gnome тепер очікують необмеженого простору адрес та не можуть працювати!
    • Замах / проблематично : overcommit політика і відношення ще один спосіб , щоб спробувати управляти і зменшити це (наприклад sysctl vm.overcommit_memory, sysctl vm.overcommit_ratio, але цей підхід не працює для мене.
    • Складне / складне : Спробуйте застосувати пріоритет cgroup до найважливіших процесів (наприклад, ssh), але це наразі здається громіздким для cgroup v1 (сподіваємось, v2 полегшить) ...

Я також виявив:

Більш довгострокове рішення

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

Деякі цікаві ділянки:

Тож не просто поганий код простору користувача та конфігурація / параметри дистрибутива, які винні - ядро ​​може це впоратися краще.

Коментарі до варіантів, що вже розглядаються

1) Вимкнути заміну

Рекомендується забезпечити хоча б невеликий розділ для заміни ( чи дійсно нам потрібен своп у сучасних системах? ). Вимкнення swap не тільки запобігає заміні невикористаних сторінок, але також може вплинути на евристичну стратегію перевиконання ядра за замовчуванням для розподілу пам’яті ( що означає евристика в Overcommit_memory = 0? ), Оскільки ця евристика враховується на сторінках підкачки. Без swap, overcommit все ще, ймовірно, може працювати в евристичному (0) або завжди (1) режимах, але поєднання no swap і стратегії over -mit never (2), ймовірно, є жахливою ідеєю. Тож у більшості випадків жоден своп, швидше за все, не пошкодить продуктивність.

Наприклад, подумайте про тривалий запущений процес, який спочатку торкається пам'яті для одноразової роботи, але потім не вдається звільнити цю пам'ять і продовжує працювати у фоновому режимі. Ядро доведеться використовувати для цього оперативну пам'ять, поки процес не закінчиться. Без будь-якого свопу ядро ​​не може розкрити його для чогось іншого, що насправді хоче активно використовувати ОЗУ. Також подумайте про те, скільки дивовижних ледачих і не звільняйте явно пам'ять після використання.

3) встановити максимальну кількість пам'яті

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

4) зберігайте важливі програми (X11, bash, kill, top, ...) у пам'яті і ніколи не змінюйте їх

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

випуск systemd 232 щойно додав деякі параметри, які роблять це можливим: я думаю, що можна використовувати "MemorySwapMax = 0", щоб запобігти блоку (службі) на зразок ssh, щоб будь-яка його пам'ять була замінена.

Тим не менш, можливість мати пріоритетний доступ до пам'яті було б краще.

Довге пояснення

Ядро Linux більше налаштоване на завантаження сервера, тому реакція на графічний інтерфейс, на жаль, є вторинною проблемою ... Налаштування управління пам’яттю ядра в Desktop Edition Ubuntu 16.04 LTS, схоже, не відрізняються від інших версій сервера. Він навіть відповідає за замовчуванням у RHEL / CentOS 7.2, зазвичай використовується як сервер.

OOM, Ulimit і торгуючи цілісністю для чуйності

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

Я сподіваюся, що налаштування Linux OOM, що надходять у новіших ядрах, визнають, що цей робочий набір перевищує ситуацію з фізичною пам'яттю і вбиває процес. Коли цього не відбувається, трапляється проблема молотіння. Проблема полягає в тому, що при великому розділі swap це може виглядати так, ніби система все ще має прогол, а ядро ​​весело виконує запити на пам'ять, але робочий набір може перекинутись на своп, ефективно намагаючись ставитись до сховища так, ніби це оперативна пам'ять.

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

Це була хороша комічна аналогія щодо OOM: oom_pardon, він же не вбиває мій xlock

Між іншим, OOMScoreAdjustє ще одним системним варіантом, який допомагає схуднути та уникнути процесів вбивства OOM, які вважаються важливішими.

буферне списання

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

усуває обмеження

Одна з проблем, що стосуються ulimits, полягає в тому, що ліміт обліку застосовується до адресного простору віртуальної пам'яті (що має на увазі поєднання фізичного та простору обміну). Відповідно до man limits.conf:

       rss
          maximum resident set size (KB) (Ignored in Linux 2.4.30 and
          higher)

Тому встановлення обмеження на застосування лише до фізичного використання оперативної пам’яті вже не виглядає корисним. Звідси

      as
          address space limit (KB)

здається, є єдиним шанованим настроєм.

На жаль, як детальніше детальніше на прикладі WebKit / Gnome, деякі програми не можуть запускатися, якщо розподіл віртуального адресного простору обмежений.

групи повинні допомогти у майбутньому?

В даний час це здається громіздким, але можливо включити деякі прапори групи ядер cgroup_enable=memory swapaccount=1(наприклад, у конфігурації grub), а потім спробувати використовувати контролер пам'яті cgroup для обмеження використання пам'яті.

cgroups мають більш вдосконалені можливості обмеження пам'яті, ніж опції 'ulimit'. Зауваження CGroup v2 натякають на спроби покращити, як працювали уліми.

Об'єднаний облік пам’яті + своп облік та обмеження замінюється реальним контролем над простором своп.

Параметри CGroup можна встановити за допомогою системних параметрів управління ресурсами . Наприклад:

  • MemoryHigh
  • MemoryMax

Можуть бути й інші корисні варіанти

  • IOWeight
  • CPUSхарес

Вони мають деякі недоліки:

  1. Накладні. Поточна документація докера коротко згадує про 1% додаткового використання пам’яті та 10% погіршення продуктивності (можливо, що стосується операцій з розподілом пам’яті - вона насправді не вказує).
  2. Програми Cgroup / systemd останнім часом сильно переробили, тому потік вище за течією передбачає, що постачальники дистрибутивів Linux можуть чекати, коли він спочатку вирішиться.

У CGroup v2 вони припускають, що це memory.highповинен бути хорошим варіантом для придушення та управління використанням пам’яті групою процесів. Однак ця цитата говорить про те, що для моніторингу ситуацій тиску в пам'яті потрібно більше працювати (станом на 2015 рік).

Вимір тиску пам’яті - на скільки впливає навантаження на роботу через брак пам’яті - необхідний, щоб визначити, чи потрібно навантаженість більше пам’яті; на жаль, механізм моніторингу тиску в пам'яті ще не запроваджений.

Враховуючи складні засоби користувальницького простору systemd та cgroup, я не знайшов простого способу встановити щось відповідне і використовувати це далі. Документація для групи та systemd для Ubuntu не велика. Майбутня робота повинна бути для дистрибутива з виданнями для настільних комп'ютерів, щоб використовувати групи та systemd, щоб при високому тиску пам’яті, ssh та компоненти X-Server / window window отримували більш високий пріоритетний доступ до процесора, фізичної оперативної пам’яті та IO для зберігання даних, щоб уникнути конкуренції процесам зайнятий обмін. Особливості пріоритету процесора ядра та вводу / виводу ядра вже деякий час існують. Здається, пріоритетний доступ до фізичної ОЗУ, якої не вистачає.

Однак навіть пріоритети CPU та IO не встановлені належним чином? Коли я перевірив обмеження системних груп, застосував частки процесора тощо, наскільки я міг сказати, Ubuntu не випікав жодних заздалегідь визначених пріоритетів. Наприклад, я біг:

systemctl show dev-mapper-Ubuntu\x2dswap.swap

Я порівняв це з тим самим виходом для ssh, samba, gdm та nginx. Важливі речі, такі як графічний інтерфейс та віддалена консоль адміністратора, повинні рівномірно боротися з усіма іншими процесами, коли трапляється обмолот.

Приклад обмежень пам'яті у мене в системі 16 Гб оперативної пам'яті

Я хотів увімкнути сплячку, тому мені знадобився великий розділ для заміни. Звідси намагання пом'якшити улімит тощо.

позбавити

Я ставлю * hard as 16777216в /etc/security/limits.d/mem.confтакі , що жоден процес не буде дозволено вимагати більше пам'яті , ніж фізично можливо. Я не заважую обмолочувати всіх разом, але без цього лише один процес із жадібним використанням пам'яті або витоком пам’яті може призвести до обмолоту. Наприклад, я бачив, як gnome-contactsвисмоктуєте 8 ГБ + пам'яті, роблячи звичні речі, такі як оновлення глобального списку адрес з сервера обміну ...

Контакти Gnome розжовують оперативну пам'ять

Як бачимо з ulimit -S -v, у багатьох дистрибутивах цей жорсткий і м'який ліміт встановлений як "необмежений", дається, теоретично, процес може в кінцевому підсумку вимагати багато пам'яті, але тільки активно, використовуючи підмножину, і запускати щасливо, думаючи, що йому дали 24 Гб оперативної пам’яті, поки у системі лише 16 Гб. Вищеописаний жорсткий ліміт призведе до того, що процеси, які, можливо, змогли б нормально перерватись, коли ядро ​​заперечує їх жадібні спекулятивні запити на пам'ять.

Однак він також ловить божевільні речі, такі як контакти гнома, і замість того, щоб втратити чутливість мого робочого столу, я отримую помилку "недостатньо вільної пам'яті":

введіть тут опис зображення

Ускладнення, що встановлюють обмеження для адресного простору (віртуальна пам'ять)

На жаль, деякі розробники люблять робити вигляд, що віртуальна пам'ять - це нескінченний ресурс, і встановлення доступу до віртуальної пам'яті може зламати деякі програми. Наприклад, WebKit (від якого залежать деякі програми gnome) додав функцію gigacageзахисту, яка намагається виділити божевільні кількості віртуальної пам’яті та трапляються FATAL: Could not allocate gigacage memoryпомилки з нахабною підказкою Make sure you have not set a virtual memory limit. Обхід,GIGACAGE_ENABLED=noвідмовляється від переваг безпеки, але так само, якщо заборонено обмежувати розподіл віртуальної пам'яті, це також відмовляється від функції захисту (наприклад, управління ресурсами, що може запобігти відмову в обслуговуванні). Як не дивно, між gigacage та gnome dev, вони, здається, забувають, що обмеження розподілу пам’яті є самим контролем безпеки. І, на жаль, я помітив, що програми gnome, які покладаються на gigacage, не намагаються явно вимагати більш високої межі, тому навіть м'який ліміт порушує речі в цьому випадку.

Якщо чесно, якщо ядро ​​зробило кращу роботу, щоб заперечувати розподіл пам'яті на основі використання резидентної пам'яті замість віртуальної пам'яті, то робити вигляд, що віртуальна пам'ять є необмеженою, було б менш небезпечно.

перевиконувати

Якщо ви віддаєте перевагу програмам, яким заборонено доступ до пам’яті, і ви хочете припинити надмірну передачу даних, скористайтеся командами нижче, щоб перевірити, як поводиться ваша система під високим тиском пам'яті.

У моєму випадку коефіцієнт фіксації за замовчуванням був:

$ sysctl vm.overcommit_ratio
vm.overcommit_ratio = 50

Але він набуває повного ефекту лише при зміні політики, щоб відключити перевиконання та застосувати коефіцієнт

sudo sysctl -w vm.overcommit_memory=2

Коефіцієнт, що передбачає лише 24 ГБ пам'яті, може бути виділений загалом (16 ГБ оперативної пам’яті * 0,5 + 16 ГБ SWAP). Тож я, мабуть, ніколи не бачив, щоб OOM з'являвся, і фактично було б менше шансів, щоб процеси постійно отримували доступ до пам'яті свопом. Але я, ймовірно, буду жертвувати загальну ефективність системи.

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

Як працює VM з перезарядкою пам'яті, має більше інформації.

Я вирішив повернутись до цього за замовчуванням sudo sysctl -w vm.overcommit_memory=0, враховуючи весь графічний стек робочого столу та додатки на ньому, тим не менш, виходять з ладу.


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

2
but the kernel won't be able to use an overcommit strategy for allocating memory and this will likely hurt performance. Even a smaller swap partition allows this. Чи є докази цьому? Я вважаю, що ядро ​​перемагає просто без налаштування свопу
ygrek

@ygrek, спасибі, що формулювання виглядає досить неправильно - overcommit все ще працює без заміни, якщо не обраний режим ніколи не перевиконувати (2). Евристичний режим перевиконання за замовчуванням (0) або режими завжди виконувати (1), ймовірно, все ще працюють без заміни. Не можу пригадати, де я читав, що вимкнення swap шкодить здатності коду перевиконання розподіляти пам'ять (і в якому режимі це впливає конкретно). Гугл знову без удачі, але це була напівкорисна публікація: stackoverflow.com/questions/38688824/… Я відповідь відповідним чином відредагую.
JPvRiel

Я сподівався, що виправлення фонового виправлення допоможе мені, але я перебуваю на зовсім новому ядрі (4.14.81) і зіштовхнувся зі значними проблемами реагування під час важкого дискового вводу-виводу (незалежно від того, причина заміни чи ні). Цікаво, чи диспетчер пристроїв чи моє шифрування LUKS якимось чином викликають проблеми з продуктивністю. У мене справді мало поняття, як налагодити подібну проблему.
Дарій Джагандарі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.