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 можна встановити за допомогою системних параметрів управління ресурсами . Наприклад:
Можуть бути й інші корисні варіанти
Вони мають деякі недоліки:
- Накладні. Поточна документація докера коротко згадує про 1% додаткового використання пам’яті та 10% погіршення продуктивності (можливо, що стосується операцій з розподілом пам’яті - вона насправді не вказує).
- Програми 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 ГБ + пам'яті, роблячи звичні речі, такі як оновлення глобального списку адрес з сервера обміну ...
Як бачимо з 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
, враховуючи весь графічний стек робочого столу та додатки на ньому, тим не менш, виходять з ладу.