Что убило мой процесс и почему?

614

Мое приложение работает в Linux как фоновый процесс. В настоящее время он запускается из командной строки в окне терминала.

Недавно пользователь некоторое время выполнял приложение, и оно загадочным образом умерло. Текст:

убитый

был на терминале. Это случилось два раза. Я спросил, использует ли кто-то в другом Терминале команду kill для уничтожения процесса? Нет.

При каких условиях Linux решит убить мой процесс? Я полагаю, что оболочка показала «kill», потому что процесс умер после получения сигнала kill (9). Если Linux отправил сигнал уничтожения, должно ли быть какое-то сообщение в системном журнале, объясняющее, почему оно было убито?

SBQ
источник
23
Linux убил мой процесс и зарегистрировал его в / var / log / messages на redhat
Дин Хиллер,
1
Смотрите также этот ответ на unix.stackexchange.com.
Ричард
В этом событии участвуют 3 игрока: (1) Процесс, который (общая причина) занимает слишком много памяти и вызывает условие OOM (2) Ядро, которое отправляет сигнал SIGKILL (сигнал 9), чтобы завершить его, и регистрирует факт в некоторой системе. log like /var/log/messages(3) Оболочка, под которой запущен процесс, который является процессом, который печатает Killedуведомление, когда состояние выхода из waitpid(2)указывает, что дочерний процесс умер от сигнала 9.
arielf
После прочтения @ ответ DeanHiller, я нашел сообщения лога на Ubuntu под/var/log/syslog
Dinei

Ответы:

403

Если пользователь или системный администратор не убили программу, возможно, ядро. Ядро будет убивать процесс только в исключительных обстоятельствах, таких как чрезвычайное истощение ресурсов (например, mem + swap исчерпание).

DWC
источник
25
Если ядро ​​уничтожит процесс, оно куда-нибудь поместит сообщение в лог?
суббота,
186
Я только что написал программу, которая malloc'd память в бесконечном цикле. После того, как система заработала медленно, в терминале отображалось «Killed», и процесс был остановлен. Файл /var/log/kern.log содержит много информации о прекращении. -Спасибо за указатель.
суббота,
6
Это почти наверняка. Я много видел это во время обучения. Многие студенты забудут освободить свои объекты, и приложения в конечном итоге достигнут 3 ГБ виртуальной памяти. Как только он достиг этого пункта, его убили.
Herms
8
Когда «просто происходит сбой программы», это означает, что ОС фактически убивает процесс!
Бернд Джендриссек
79
Используйте, dmesgчтобы просмотреть журнал ядра: здесь я обнаружил, что процессы Python, убитые ядром из-за чрезмерного потребления виртуальной памяти.
caneta
273

Пытаться:

dmesg -T| grep -E -i -B100 'killed process'

Где -B100обозначает количество строк до того, как произошло уничтожение.

Опустить -T в Mac OS.

Равиндранат Акила
источник
6
К вашему сведению, из info egrep: "egrep - это то же самое, что и grep -E. ... Прямой вызов как egrep или fgrep устарел"
Air
9
В случае простого шаблона, как 'killed process'вы можете просто использовать grepвместо egrepдругих изменений. Для более сложного паттерна вы должны заменить заменить, например, egrep -i -B100 'foo|ba[rz]'на grep -E -i -B100 'foo|ba[rz]'. Этот Q & A дает больше деталей.
эфир
2
Я также предложил бы использовать dmesg -Tдля того, чтобы получить читаемые метки времени
gukoff
171

Это похоже на хорошую статью на эту тему: Укрощение убийцы ООМ .

Суть в том, что Linux преодолеваетПамять. Когда процесс запрашивает больше места, Linux предоставит ему это пространство, даже если это запрашивается другим процессом, при условии, что никто фактически не использует всю запрашиваемую им память. Процесс получит исключительное использование памяти, которую он выделил, когда он фактически использует ее, а не когда он запрашивает ее. Это делает распределение быстрым и может позволить вам «обмануть» и выделить больше памяти, чем у вас есть на самом деле. Однако, как только процессы начнут использовать эту память, Linux может понять, что она слишком щедра в распределении памяти, которой у нее нет, и ей придется убить процесс, чтобы освободить его. Уничтожаемый процесс основан на оценке, учитывающей время выполнения (длительные процессы безопаснее), использование памяти (жадные процессы менее безопасны) и некоторые другие факторы, включая значение, которое вы можете настроить, чтобы сделать процесс менее вероятным уничтожение. Все это описано в статье более подробно.

Редактировать: И вот еще одна статья, которая довольно хорошо объясняет, как выбирается процесс (аннотировано некоторыми примерами кода ядра). Самое замечательное в этом то, что он включает в себя некоторые комментарии к обоснованию различных badness()правил.

Адам Яскевич
источник
3
Я действительно люблю ссылки на статьи. Я бы предложил всем, кто интересуется этой темой, прочитать их, особенно комментарии к статье lwn.
Джон Брингхерст
4
«Linux предоставит ему это пространство, даже если на него претендует другой процесс». Это не совсем так, как работает виртуальная память ...
Mooing Duck
1
статья довольно старая (2009 г.), и не все функциональные возможности, предлагаемые в статье, приведены в основном.
Алекс
50

Позвольте мне сначала объяснить, когда и почему вызывается OOMKiller?

Скажем, у вас есть 512 ОЗУ + 1 ГБ подкачки памяти. Теоретически, ваш процессор имеет доступ к 1,5 ГБ виртуальной памяти.

В течение некоторого времени все работает нормально в пределах 1,5 ГБ общей памяти. Но внезапно (или постепенно) ваша система начала потреблять все больше и больше памяти, и она достигла примерно 95% от общего объема используемой памяти.

Теперь скажите, что любой процесс запросил большой кусок памяти у ядра. Ядро проверит доступную память и обнаружит, что нет способа выделить вашему процессу больше памяти. Поэтому он попытается освободить память, вызывающую / вызывающую OOMKiller ( http://linux-mm.org/OOM ).

OOMKiller имеет свой собственный алгоритм для оценки рейтинга для каждого процесса. Как правило, какой процесс использует больше памяти, становится жертвой, которую нужно убить.

Где я могу найти логи OOMKiller?

Обычно в каталоге / var / log. Либо /var/log/kern.log или / var / log / dmesg

Надеюсь, что это поможет вам.

Некоторые типичные решения:

  1. Увеличение памяти (не своп)
  2. Найдите утечки памяти в вашей программе и исправьте их
  3. Ограничить память, которую может использовать любой процесс (например, память JVM может быть ограничена с помощью JAVA_OPTS)
  4. Смотрите логи и гуглите :)
Джадав Бхеда
источник
17

Это Linux из нехватки памяти (OOM) . Ваш процесс был выбран из - за « вредность » - сочетание Давности, житель размера (память используется, а не просто выделяется) и другие факторы.

sudo journalctl -xb

Вы увидите сообщение вроде:

Jul 20 11:05:00 someapp kernel: Mem-Info:
Jul 20 11:05:00 someapp kernel: Node 0 DMA per-cpu:
Jul 20 11:05:00 someapp kernel: CPU    0: hi:    0, btch:   1 usd:   0
Jul 20 11:05:00 someapp kernel: Node 0 DMA32 per-cpu:
Jul 20 11:05:00 someapp kernel: CPU    0: hi:  186, btch:  31 usd:  30
Jul 20 11:05:00 someapp kernel: active_anon:206043 inactive_anon:6347 isolated_anon:0
                                    active_file:722 inactive_file:4126 isolated_file:0
                                    unevictable:0 dirty:5 writeback:0 unstable:0
                                    free:12202 slab_reclaimable:3849 slab_unreclaimable:14574
                                    mapped:792 shmem:12802 pagetables:1651 bounce:0
                                    free_cma:0
Jul 20 11:05:00 someapp kernel: Node 0 DMA free:4576kB min:708kB low:884kB high:1060kB active_anon:10012kB inactive_anon:488kB active_file:4kB inactive_file:4kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present
Jul 20 11:05:00 someapp kernel: lowmem_reserve[]: 0 968 968 968
Jul 20 11:05:00 someapp kernel: Node 0 DMA32 free:44232kB min:44344kB low:55428kB high:66516kB active_anon:814160kB inactive_anon:24900kB active_file:2884kB inactive_file:16500kB unevictable:0kB isolated(anon):0kB isolated
Jul 20 11:05:00 someapp kernel: lowmem_reserve[]: 0 0 0 0
Jul 20 11:05:00 someapp kernel: Node 0 DMA: 17*4kB (UEM) 22*8kB (UEM) 15*16kB (UEM) 12*32kB (UEM) 8*64kB (E) 9*128kB (UEM) 2*256kB (UE) 3*512kB (UM) 0*1024kB 0*2048kB 0*4096kB = 4580kB
Jul 20 11:05:00 someapp kernel: Node 0 DMA32: 216*4kB (UE) 601*8kB (UE) 448*16kB (UE) 311*32kB (UEM) 135*64kB (UEM) 74*128kB (UEM) 5*256kB (EM) 0*512kB 0*1024kB 1*2048kB (R) 0*4096kB = 44232kB
Jul 20 11:05:00 someapp kernel: Node 0 hugepages_total=0 hugepages_free=0 hugepages_surp=0 hugepages_size=2048kB
Jul 20 11:05:00 someapp kernel: 17656 total pagecache pages
Jul 20 11:05:00 someapp kernel: 0 pages in swap cache
Jul 20 11:05:00 someapp kernel: Swap cache stats: add 0, delete 0, find 0/0
Jul 20 11:05:00 someapp kernel: Free swap  = 0kB
Jul 20 11:05:00 someapp kernel: Total swap = 0kB
Jul 20 11:05:00 someapp kernel: 262141 pages RAM
Jul 20 11:05:00 someapp kernel: 7645 pages reserved
Jul 20 11:05:00 someapp kernel: 264073 pages shared
Jul 20 11:05:00 someapp kernel: 240240 pages non-shared
Jul 20 11:05:00 someapp kernel: [ pid ]   uid  tgid total_vm      rss nr_ptes swapents oom_score_adj name
Jul 20 11:05:00 someapp kernel: [  241]     0   241    13581     1610      26        0             0 systemd-journal
Jul 20 11:05:00 someapp kernel: [  246]     0   246    10494      133      22        0         -1000 systemd-udevd
Jul 20 11:05:00 someapp kernel: [  264]     0   264    29174      121      26        0         -1000 auditd
Jul 20 11:05:00 someapp kernel: [  342]     0   342    94449      466      67        0             0 NetworkManager
Jul 20 11:05:00 someapp kernel: [  346]     0   346   137495     3125      88        0             0 tuned
Jul 20 11:05:00 someapp kernel: [  348]     0   348    79595      726      60        0             0 rsyslogd
Jul 20 11:05:00 someapp kernel: [  353]    70   353     6986       72      19        0             0 avahi-daemon
Jul 20 11:05:00 someapp kernel: [  362]    70   362     6986       58      18        0             0 avahi-daemon
Jul 20 11:05:00 someapp kernel: [  378]     0   378     1621       25       8        0             0 iprinit
Jul 20 11:05:00 someapp kernel: [  380]     0   380     1621       26       9        0             0 iprupdate
Jul 20 11:05:00 someapp kernel: [  384]    81   384     6676      142      18        0          -900 dbus-daemon
Jul 20 11:05:00 someapp kernel: [  385]     0   385     8671       83      21        0             0 systemd-logind
Jul 20 11:05:00 someapp kernel: [  386]     0   386    31573      153      15        0             0 crond
Jul 20 11:05:00 someapp kernel: [  391]   999   391   128531     2440      48        0             0 polkitd
Jul 20 11:05:00 someapp kernel: [  400]     0   400     9781       23       8        0             0 iprdump
Jul 20 11:05:00 someapp kernel: [  419]     0   419    27501       32      10        0             0 agetty
Jul 20 11:05:00 someapp kernel: [  855]     0   855    22883      258      43        0             0 master
Jul 20 11:05:00 someapp kernel: [  862]    89   862    22926      254      44        0             0 qmgr
Jul 20 11:05:00 someapp kernel: [23631]     0 23631    20698      211      43        0         -1000 sshd
Jul 20 11:05:00 someapp kernel: [12884]     0 12884    81885     3754      80        0             0 firewalld
Jul 20 11:05:00 someapp kernel: [18130]     0 18130    33359      291      65        0             0 sshd
Jul 20 11:05:00 someapp kernel: [18132]  1000 18132    33791      748      64        0             0 sshd
Jul 20 11:05:00 someapp kernel: [18133]  1000 18133    28867      122      13        0             0 bash
Jul 20 11:05:00 someapp kernel: [18428]    99 18428   208627    42909     151        0             0 node
Jul 20 11:05:00 someapp kernel: [18486]    89 18486    22909      250      46        0             0 pickup
Jul 20 11:05:00 someapp kernel: [18515]  1000 18515   352905   141851     470        0             0 npm
Jul 20 11:05:00 someapp kernel: [18520]     0 18520    33359      291      66        0             0 sshd
Jul 20 11:05:00 someapp kernel: [18522]  1000 18522    33359      294      64        0             0 sshd
Jul 20 11:05:00 someapp kernel: [18523]  1000 18523    28866      115      12        0             0 bash
Jul 20 11:05:00 someapp kernel: Out of memory: Kill process 18515 (npm) score 559 or sacrifice child
Jul 20 11:05:00 someapp kernel: Killed process 18515 (npm) total-vm:1411620kB, anon-rss:567404kB, file-rss:0kB
mikemaccana
источник
12

Как заявили dwc и Адам Яскевич, виновник, скорее всего, убийца ООМ. Тем не менее, следующий вопрос, который следует: как я могу предотвратить это?

Есть несколько способов:

  1. Дайте вашей системе больше оперативной памяти, если вы можете (легко, если это виртуальная машина)
  2. Убедитесь, что убийца OOM выбирает другой процесс.
  3. Отключить OOM Killer
  4. Выберите дистрибутив Linux, который поставляется с отключенным OOM Killer.

Благодаря этой статье я нашел, что (2) особенно легко реализовать .

деревенщина
источник
2
Это была оперативная память для меня. Я обновил с 2 до 4 ГБ ОЗУ и проблема исчезла. Теперь проблема со счетом: P
Gus
9

Модуль PAM для ограничения ресурсов вызвал именно те результаты, которые вы описали: мой процесс загадочным образом заглох с текстом « Killed» в окне консоли. Нет вывода журнала, ни в системном журнале, ни в kern.log . Верхняя программа помогла мне узнать , что именно после того, как одна минута использования процессора мой процесс погибает.

Кристиан Аммер
источник
8

Такой инструмент, как systemtap (или трассировщик), может контролировать логику передачи сигналов ядра и создавать отчеты. например, https://sourceware.org/systemtap/examples/process/sigmon.stp

# stap .../sigmon.stp -x 31994 SIGKILL
   SPID     SNAME            RPID  RNAME            SIGNUM SIGNAME
   5609     bash             31994 find             9      SIGKILL

Блок фильтрации ifв этом сценарии может быть настроен по вкусу или исключен для отслеживания общесистемного сигнального трафика. Причины могут быть дополнительно изолированы путем сбора обратных следов (добавьте a print_backtrace()и / или print_ubacktrace()к зонду для ядра и пользовательского пространства соответственно).

fche
источник
4

В среде lsf (интерактивной или иной), если приложение превышает использование памяти сверх некоторого заданного порога администраторами в очереди или запросом ресурсов при отправке в очередь, процессы будут убиты, поэтому другие пользователи не станут жертвами потенциального убегай. При этом он не всегда отправляет электронное письмо, в зависимости от того, как он настроен.

Одним из решений в этом случае является поиск очереди с большими ресурсами или определение больших требований к ресурсам в представлении.

Вы также можете рассмотреть man ulimit

Хотя я не помню , в ulimitрезультате чего Killedего было некоторое время , так как я нуждался в этом.

старик
источник
2

У нас периодически возникали проблемы под Linux на сайте заказчика (я думаю, в Red Hat), когда OOMKiller (убийца нехватки памяти) убивал как наше основное приложение (т. Е. Причину существования сервера), так и процессы базы данных.

В каждом случае OOMKiller просто решал, что процессы используют слишком много ресурсов ... машина даже не собирается выходить из строя из-за нехватки ресурсов. Ни у приложения, ни у его базы данных нет проблем с утечками памяти (или любой другой утечкой ресурсов).

Я не эксперт по Linux, но скорее собрал его алгоритм для решения, когда убивать что-то, а что убивать - это сложно. Кроме того, мне сказали (я не могу говорить о точности этого), что OOMKiller запекается в ядре, и вы просто не можете его запустить.

Лоуренс Дол
источник
1
IIRC, OOMKiller используется только как последнее средство. Я думаю, что система даже отправит сигнал различным приложениям с просьбой отказаться от некоторых ресурсов, прежде чем она будет вынуждена вызвать OOMKiller. Возьмите с собой
крупичку
1
Вы можете просто не запускать его. Он встроен в ядро, но есть варианты настройки его работы и даже процессов, которые он может убить. Он запускается, когда всей системе не хватает памяти, а не когда конкретный процесс использует слишком много. Смотрите мой ответ для более подробной информации.
Адам Яскевич
6
Не запустить oomkiller довольно легко. echo "2" > /proc/sys/vm/overcommit_memory
R .. GitHub ОСТАНОВИТЬ ЛЬДА
Red Hat не хочет, чтобы его можно было изменить: sudo echo "2" > /proc/sys/vm/overcommit_memory/ proc / sys / vm / overcommit_memory: В доступе отказано
Брент Фауст,
2
Попробуйтеecho 2 | sudo tee /proc/sys/vm/overcommit_memory
Hypershadsy
2

В моем случае это происходило с работником очереди Laravel. В системных журналах не было упоминаний о каких-либо убийствах, поэтому я посмотрел дальше, и оказалось, что рабочий в основном убивал себя из-за задания, которое превысило ограничение памяти (которое по умолчанию установлено на 128 МБ).

Запуск работника очереди с --timeout=600и --memory=1024исправил проблему для меня.

iSWORD
источник
0

Пользователь имеет возможность убивать свои собственные программы, используя kill или Control + C, но у меня складывается впечатление, что это не то, что произошло, и что пользователь пожаловался вам.

Конечно, root имеет возможность убивать программы, но если кто-то имеет root на вашей машине и убивает вещи, у вас большие проблемы.

Если вы не являетесь системным администратором, возможно, системный администратор установил квоты на использование ЦП, ОЗУ, использование орт-диска и процессы автоматического уничтожения, которые превышают их.

Кроме этих догадок, я не уверен без дополнительной информации о программе.

Том Риттер
источник
6
CTRL-C отправляет сообщение об уничтожении, отличное от сообщенного OP (SIGINT (2), насколько я помню, тогда как программа получает SIGKILL (9)).
Powerlord
0

Я столкнулся с этой проблемой в последнее время. Наконец, я обнаружил, что мои процессы были уничтожены сразу после автоматического вызова обновления OpenSuse zypper. Чтобы отключить обновление zypper решил мою проблему.

poordeveloper
источник
Я вижу ту же проблему. Как вы отследили, какой процесс убил ваш процесс? Кажется, есть инструмент для проверки того, кто отправляет SIGKILL процессу.
Howy
0

Решил эту проблему, увеличив размер свопа :

/ubuntu/1075505/how-do-i-increase-swapfile-in-ubuntu-18-04

Lejla
источник
3
Пожалуйста, не публикуйте ответы только на ссылки на другие вопросы по Stack Exchange. Вместо этого, включите основные части ответа здесь, и адаптируйте ответ на этот конкретный вопрос.
двойной сигнал