Як швидко зупинити процес, який спричиняє обмолот (через надлишок розподілу пам'яті)?


19

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

Я останнім часом це відчував на своєму ноутбуці Ubuntu завдяки сценарію Matlab, який намагався виділити смішно величезну матрицю. Після ~ 5 + хвилин обмолоту я зміг Ctrl-F1 до консолі та вбити Matlab. Я набагато скоріше мав би гарячу клавішу, яка дала б мені керування системою негайно і дозволила мені вбити процес, що порушує правопорушення; або, можливо, просто мовчки відмовляються виділяти такий великий буфер.

  1. Який найшвидший спосіб відновити контроль над системою Linux, яка стала невідповідною або надзвичайно млявою через надмірну заміну?

  2. Чи існує ефективний спосіб запобігти виникненню таких замінів, наприклад, обмеженням обсягу пам'яті, який дозволено спробувати виділити?

Відповіді:


12

Натисніть Alt-SysRq-F, щоб вбити процес, використовуючи найбільшу пам'ять:

  • Клавіша SysRq зазвичай відображається на ключ друку.
  • Якщо ви використовуєте графічний робочий стіл, можливо, вам доведеться натиснути Ctrl-Alt-SysRq-F у випадку, якщо натискання Alt-SysRq запускає іншу дію (наприклад, програма знімка).
  • Якщо ви користуєтесь ноутбуком, можливо, вам також знадобиться натиснути функціональну клавішу.
  • Для отримання додаткової інформації читайте статтю wikipedia .

5

Я зробив для цього сценарій - https://github.com/tobixen/thrash-protect

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

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


Щодо відключення swap, згідно з unix.stackexchange.com/a/24646/9108, це може бути не найкращим варіантом.
sashoalm

Дійсно, хтось так само прокоментував мене, тож я змінив документацію щодо захисту від трешів у той момент.
tobixen

4
  1. Який найшвидший спосіб відновити контроль над системою Linux, яка стала невідповідною або надзвичайно млявою через надмірну заміну?

Вже відповів вище за допомогою Alt-SysRq-F

  1. Чи існує ефективний спосіб запобігти виникненню таких замінів, наприклад, обмеженням обсягу пам'яті, який дозволено спробувати виділити?

Я відповідаю на цю 2-ю частину. Так, ulimitвсе ще працює досить добре, щоб обмежити один процес. Ти можеш:

  • встановіть м'який ліміт для процесу, який ви знаєте, ймовірно, вийде з-під контролю
  • встановіть жорсткий ліміт для всіх процесів, якщо ви хочете отримати додаткову страховку

Також, як коротко згадувалося:

Ви можете використовувати CGroups для обмеження використання ресурсів та запобігання таких проблем

Дійсно, групи пропонують більш досконалий контроль, але наразі на мою думку складніше налаштувати.

Стара школа ulimit

Одного разу вимкнений

Ось простий приклад:

$ bash
$ ulimit -S -v $((1*2**20))
$ r2(){r2 $@$@;};r2 r2
bash: xmalloc: .././subst.c:3550: cannot allocate 134217729 bytes (946343936 bytes allocated)

Це:

  • Встановлює м'який ліміт загального обсягу використання пам’яті 1 Гб (зменшення припускає ліміт у кБ)
  • Виконує рекурсивний виклик функції bash, r2(){ r2 $@$@;};r2 r2який буде експоненціально розжувати процесор і оперативну пам'ять, нескінченно подвоюючи себе, вимагаючи стека пам'яті.

Як бачите, його зупинили при спробі запитувати більше 1 Гб.

Зауважте, -vдіє на розподіл віртуальної пам'яті (загальний, тобто фізичний + своп).

Постійний захист

Щоб обмежити розподіл віртуальної пам'яті, asце еквівалент -vдля limits.conf.

Я роблю такі дії, щоб захистити від будь-якого одного недобросовісного процесу:

  • Встановіть обмежений простір адресного простору для всіх процесів.
  • address space limit = <physical memory> - 256MB.
  • Тому жоден процес із жадібним використанням пам'яті або активним циклом та витоком пам’яті не може споживати ВСЮ фізичну пам'ять.
  • Розміщення на 256 МБ є необхідним для оброблення файлом ssh або консоллю.

Один вкладиш:

$ sudo bash -c "echo -e \"*\thard\tas\t$(($(grep -E 'MemTotal' /proc/meminfo | grep -oP '(?<=\s)\d+(?=\skB$)') - 256*2**10))\" > /etc/security/limits.d/mem.conf"

Для перевірки це призводить до наступного (наприклад, у системі 16 ГБ):

$ cat /etc/security/limits.d/mem.conf
*   hard    as      16135196
$ ulimit -H -v
161351960

Примітки:

  • Лише пом'якшує процес, який перебуває за бортом із використанням пам'яті.
  • Не завадить багатопроцесовий навантаження з великим тиском пам’яті, що спричиняє молотіння (тоді група відповіді).
  • Не використовуйте rssпараметр у limit.conf. Нові ядра не поважаються.
  • Це консервативно.
    • Теоретично процес може спекулятивно вимагати великої кількості пам'яті, але лише активно використовувати підмножину (менший робочий набір / використання резидентної пам'яті).
    • Вищеописаний жорсткий ліміт призведе до переривання таких процесів (навіть якщо вони могли б інакше спрацювати, якщо Linux дозволяє надмірно передавати адресний простір віртуальної пам'яті).

Новіші групи CG

Забезпечує більше контролю, але в даний час більш складний у використанні:

  • Поліпшується безперервна пропозиція.
    • memory.max_usage_in_bytes може обліковувати та обмежувати фізичну пам'ять окремо.
    • Тоді як ulimit -mі / або rssв limits.confмалося на увазі пропонувати подібну функціональність, але це не працює з ядра Linux 2.4.30!
  • Потрібно включити деякі ядра контрольної групи прапорів в засобі завантаження: cgroup_enable=memory swapaccount=1.
    • Це не сталося за замовчуванням з Ubuntu 16.04.
    • Можливо, через деякі наслідки для ефективності додаткових накладних витрат.
  • Програми cgroup / systemd є відносно новими і досить мінливими, тому потік вище за течією передбачає, що постачальники дистрибутивів Linux ще не зробили його легким у використанні. Між 14.04LTS та 16.04LTS, інструмент користувальницького простору змінився для використання груп.
    • cgm тепер, здається, є офіційно підтримуваним інструментом простору користувачів.
    • Файли системних одиниць ще не мають жодних заздалегідь визначених параметрів "постачальник / дистрибутив", які надають пріоритет таким важливим службам, як ssh.

Наприклад, щоб перевірити поточні налаштування:

$ echo $(($(cat /sys/fs/cgroup/memory/memory.max_usage_in_bytes) / 2**20)) MB
11389 MB
$ cat /sys/fs/cgroup/memory/memory.stat
...

Наприклад, щоб обмежити пам'ять одного процесу:

$ cgm create memory mem_1G
$ cgm setvalue memory mem_1G memory.limit_in_bytes $((1*2**30))
$ cgm setvalue memory mem_1G memory.memsw.limit_in_bytes $((1*2**30))
$ bash
$ cgm movepid memory mem_1G $$
$ r2(){ r2 $@$@;};r2 r2
Killed

Щоб побачити це в дії, що розжовує оперативну пам'ять як фоновий процес, а потім вбиває:

$ bash -c 'cgm movepid memory mem_1G $$; r2(){ r2 $@$@;};r2 r2' & while [ -e /proc/$! ]; do ps -p $! -o pcpu,pmem,rss h; sleep 1; done
[1] 3201
 0.0  0.0  2876
 102  0.2 44056
 103  0.5 85024
 103  1.0 166944
 ...
98.9  5.6 920552
99.1  4.3 718196
[1]+  Killed                  bash -c 'cgm movepid memory mem_1G $$; r2(){ r2 $@$@;};r2 r2'

Зверніть увагу на експоненціальне (потужність 2) зростання запитів на пам'ять.

Надалі сподіваємось побачити "distro / vendors" попередньо налаштувати пріоритети та обмеження для групи (через системні блоки) для таких важливих речей, як SSH та графічний стек, щоб вони ніколи не голодували пам'яті.


2

Ви можете натиснути Ctrl- zщоб призупинити програму. Тоді ви можете зробити kill %1(або будь-який номер завдання або можете використовувати PID).

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


Ctrl-Z є приємним, але зазвичай я запускаю графічний інтерфейс Matlab і втрачаю трек керуючого терміналу, тому у мене немає простого способу видавити клавішу Ctrl-Z. Було б добре, якби у GUI була гаряча клавіша для надсилання SIGSTOP до будь-якої програми, на яку зосереджено увагу!
nibot

Ви можете запустити, kill -STOP <pid>який зробить те саме, що і Ctrl-Z.
hlovdal

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

1

Ви можете використовувати CGroups для обмеження використання ресурсів та запобігання таких проблем: https://en.wikipedia.org/wiki/Cgroups


Будь ласка, включіть у свою відповідь основну інформацію та використовуйте посилання лише для атрибуції та подальшого читання. Це посилання описує, що таке CGroups, але з посилання очевидно, як насправді використовувати його для вирішення проблеми. Чи можете ви розширити свою відповідь, щоб описати рішення питання? Спасибі.
fixer1234

0

Було б добре, якби у GUI була гаряча клавіша для надсилання SIGSTOP до будь-якої програми, на яку зосереджено увагу!

Завжди є класична xkillкоманда (від xorg-x11-apps-7.4-14.fc14.src.rpm у моїй системі). Я думаю, що не повинно бути надто складно зробити клон, який надсилає SIGSTOP замість того, щоб вбити цільове вікно.


Як я можу змусити xkill швидко запускатися при натисканні якоїсь комбінації клавіш?
nibot

Я не впевнений. Я припускаю, що і gnome, і KDE мають деякий глобальний ярлик, який можна використовувати для запуску програм.
hlovdal
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.