Как заставить Linux OOM killer не убивать мой процесс?

Как мне заставить Linux OOM killer не уничтожать мои процессы, когда физической памяти мало, но есть много места для подкачки?

Я отключил удаление OOM и избыточную фиксацию с помощью sysctl vm.overcommit_memory = 2.

В виртуальной машине есть 3 ГБ абсолютно бесплатного нефрагментированного свопа, а процессы, которые уничтожаются OOM, имеют максимальное использование памяти менее 200 МБ.

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

Mar  7 02:43:11 myhost kernel: memcheck-amd64- invoked oom-killer: gfp_mask=0x24002c2, order=0, oom_score_adj=0
Mar  7 02:43:11 myhost kernel: memcheck-amd64- cpuset=/ mems_allowed=0
Mar  7 02:43:11 myhost kernel: CPU: 0 PID: 3841 Comm: memcheck-amd64- Not tainted 4.4.0-x86_64-linode63 #2
Mar  7 02:43:11 myhost kernel: Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.8.2-0-g33fbe13 by qemu-project.org 04/01/2014
Mar  7 02:43:11 myhost kernel: 0000000000000000 0000000000000000 ffffffff8158cbcc ffff880032d7bc18
Mar  7 02:43:11 myhost kernel: ffffffff811c6a55 00000015118e701d ffffffff81044a8d 00000000000003e2
Mar  7 02:43:11 myhost kernel: ffffffff8110f5a1 0000000000000000 00000000000003e2 ffffffff81cf15cc
Mar  7 02:43:11 myhost kernel: Call Trace:
Mar  7 02:43:11 myhost kernel: [<ffffffff8158cbcc>] ? dump_stack+0x40/0x50
Mar  7 02:43:11 myhost kernel: [<ffffffff811c6a55>] ? dump_header+0x59/0x1dd
Mar  7 02:43:11 myhost kernel: [<ffffffff81044a8d>] ? kvm_clock_read+0x1b/0x1d
Mar  7 02:43:11 myhost kernel: [<ffffffff8110f5a1>] ? __raw_callee_save___pv_queued_spin_unlock+0x11/0x1e
Mar  7 02:43:11 myhost kernel: [<ffffffff81183316>] ? oom_kill_process+0xc0/0x34f
Mar  7 02:43:11 myhost kernel: [<ffffffff811839b2>] ? out_of_memory+0x3bf/0x406
Mar  7 02:43:11 myhost kernel: [<ffffffff81187bbd>] ? __alloc_pages_nodemask+0x8ba/0x9d8
Mar  7 02:43:11 myhost kernel: [<ffffffff811b82e8>] ? alloc_pages_current+0xbc/0xe0
Mar  7 02:43:11 myhost kernel: [<ffffffff811b096c>] ? __vmalloc_node_range+0x12d/0x20a
Mar  7 02:43:11 myhost kernel: [<ffffffff811e0e62>] ? alloc_fdtable+0x6a/0xd8
Mar  7 02:43:11 myhost kernel: [<ffffffff811b0a83>] ? __vmalloc_node+0x3a/0x3f
Mar  7 02:43:11 myhost kernel: [<ffffffff811e0e62>] ? alloc_fdtable+0x6a/0xd8
Mar  7 02:43:11 myhost kernel: [<ffffffff811b0ab0>] ? vmalloc+0x28/0x2a
Mar  7 02:43:11 myhost kernel: [<ffffffff811e0e62>] ? alloc_fdtable+0x6a/0xd8
Mar  7 02:43:11 myhost kernel: [<ffffffff811e1338>] ? dup_fd+0x103/0x1f0
Mar  7 02:43:11 myhost kernel: [<ffffffff810dd143>] ? copy_process+0x5aa/0x160d
Mar  7 02:43:11 myhost kernel: [<ffffffff8110f5a1>] ? __raw_callee_save___pv_queued_spin_unlock+0x11/0x1e
Mar  7 02:43:11 myhost kernel: [<ffffffff810de2fc>] ? _do_fork+0x7d/0x291
Mar  7 02:43:11 myhost kernel: [<ffffffff810ea186>] ? __set_current_blocked+0x47/0x52
Mar  7 02:43:11 myhost kernel: [<ffffffff810ea1f2>] ? sigprocmask+0x61/0x6a
Mar  7 02:43:11 myhost kernel: [<ffffffff81998eae>] ? entry_SYSCALL_64_fastpath+0x12/0x71
Mar  7 02:43:11 myhost kernel: Mem-Info:
Mar  7 02:43:11 myhost kernel: active_anon:15 inactive_anon:18 isolated_anon:0
Mar  7 02:43:11 myhost kernel: active_file:7 inactive_file:8 isolated_file:0
Mar  7 02:43:11 myhost kernel: unevictable:0 dirty:3 writeback:26 unstable:0
Mar  7 02:43:11 myhost kernel: slab_reclaimable:1798 slab_unreclaimable:3674
Mar  7 02:43:11 myhost kernel: mapped:8 shmem:1 pagetables:752 bounce:0
Mar  7 02:43:11 myhost kernel: free:1973 free_pcp:0 free_cma:0
Mar  7 02:43:11 myhost kernel: Node 0 DMA free:3944kB min:60kB low:72kB high:88kB active_anon:0kB inactive_anon:0kB active_file:28kB inactive_file:32kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:15992kB managed:15908kB
 mlocked:0kB dirty:0kB writeback:0kB mapped:0kB shmem:0kB slab_reclaimable:72kB slab_unreclaimable:236kB kernel_stack:48kB pagetables:60kB unstable:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:36
0 all_unreclaimable? yes
Mar  7 02:43:11 myhost kernel: lowmem_reserve[]: 0 972 972 972
Mar  7 02:43:11 myhost kernel: Node 0 DMA32 free:3948kB min:3956kB low:4944kB high:5932kB active_anon:60kB inactive_anon:72kB active_file:0kB inactive_file:0kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:1032064kB manag
ed:999552kB mlocked:0kB dirty:12kB writeback:104kB mapped:32kB shmem:4kB slab_reclaimable:7120kB slab_unreclaimable:14460kB kernel_stack:2112kB pagetables:2948kB unstable:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB writeback_t
mp:0kB pages_scanned:792 all_unreclaimable? yes
Mar  7 02:43:11 myhost kernel: lowmem_reserve[]: 0 0 0 0
Mar  7 02:43:11 myhost kernel: Node 0 DMA: 20*4kB (UM) 17*8kB (UM) 13*16kB (M) 14*32kB (UM) 8*64kB (UM) 4*128kB (M) 4*256kB (M) 0*512kB 1*1024kB (M) 0*2048kB 0*4096kB = 3944kB
Mar  7 02:43:11 myhost kernel: Node 0 DMA32: 934*4kB (UM) 28*8kB (UM) 0*16kB 0*32kB 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 3960kB
Mar  7 02:43:11 myhost kernel: 71 total pagecache pages
Mar  7 02:43:11 myhost kernel: 42 pages in swap cache
Mar  7 02:43:11 myhost kernel: Swap cache stats: add 245190, delete 245148, find 77026/136093
Mar  7 02:43:11 myhost kernel: Free swap  = 3118172kB
Mar  7 02:43:11 myhost kernel: Total swap = 3334140kB
Mar  7 02:43:11 myhost kernel: 262014 pages RAM
Mar  7 02:43:11 myhost kernel: 0 pages HighMem/MovableOnly
Mar  7 02:43:11 myhost kernel: 8149 pages reserved
Mar  7 02:43:11 myhost kernel: [ pid ]   uid  tgid total_vm      rss nr_ptes nr_pmds swapents oom_score_adj name
Mar  7 02:43:11 myhost kernel: [ 2054]     0  2054     5101        1      15       4      283             0 upstart-udev-br
Mar  7 02:43:11 myhost kernel: [ 2063]     0  2063    12362        1      28       4      184         -1000 systemd-udevd
Mar  7 02:43:11 myhost kernel: [ 3342]   102  3342     9780        1      23       3       89             0 dbus-daemon
Mar  7 02:43:11 myhost kernel: [ 3423]     0  3423    10864        1      26       3       85             0 systemd-logind
Mar  7 02:43:11 myhost kernel: [ 3441]     0  3441    15344        0      34       3      184         -1000 sshd
Mar  7 02:43:11 myhost kernel: [ 3450]     0  3450     4786        0      14       3       43             0 atd
Mar  7 02:43:11 myhost kernel: [ 3451]     0  3451     5915        0      17       4       65             0 cron
Mar  7 02:43:11 myhost kernel: [ 3457]   101  3457    63962        0      28       3      202             0 rsyslogd
Mar  7 02:43:11 myhost kernel: [ 3516]     0  3516     3919        1      13       3      156             0 upstart-file-br
Mar  7 02:43:11 myhost kernel: [ 3518]     0  3518     4014        0      13       3      265             0 upstart-socket-
Mar  7 02:43:11 myhost kernel: [ 3557]     0  3557    66396        0      32       3     1802             0 fail2ban-server
Mar  7 02:43:11 myhost kernel: [ 3600]     0  3600     3956        1      13       3       39             0 getty
Mar  7 02:43:11 myhost kernel: [ 3601]     0  3601     3198        1      12       3       37             0 getty
Mar  7 02:43:11 myhost kernel: [ 3673]     0  3673    26411        1      55       3      252             0 sshd
Mar  7 02:43:11 myhost kernel: [ 3740]  1000  3740    26411        1      52       3      253             0 sshd
Mar  7 02:43:11 myhost kernel: [ 3741]  1000  3741     5561        0      16       3      431             0 bash
Mar  7 02:43:11 myhost kernel: [ 3820]   103  3820     7863        1      21       3      152             0 ntpd
Mar  7 02:43:11 myhost kernel: [ 3837]  1000  3837    31990        0      58       4    12664             0 memcheck-amd64-
Mar  7 02:43:11 myhost kernel: [ 3841]  1000  3841    32006        0      59       4    12812             0 memcheck-amd64-
Mar  7 02:43:11 myhost kernel: [ 3844]  1000  3844    31950        0      57       4    12035             0 memcheck-amd64-
Mar  7 02:43:11 myhost kernel: [ 3849]  1000  3849    31902        0      56       4    11482             0 memcheck-amd64-
Mar  7 02:43:11 myhost kernel: [ 3853]  1000  3853     1087        0       7       3       27             0 lsof
Mar  7 02:43:11 myhost kernel: [ 3854]     0  3854    26140        5      55       3      230             0 sshd
Mar  7 02:43:11 myhost kernel: [ 3855]   104  3855    15699        0      33       3      202             0 sshd
Mar  7 02:43:11 myhost kernel: Out of memory: Kill process 3841 (memcheck-amd64-) score 11 or sacrifice child
Mar  7 02:43:11 myhost kernel: Killed process 3841 (memcheck-amd64-) total-vm:128024kB, anon-rss:0kB, file-rss:0kB

Это / proc / meminfo

MemTotal:        1015460 kB
MemFree:          277508 kB
MemAvailable:     322032 kB
Buffers:            8336 kB
Cached:            42208 kB
SwapCached:        46088 kB
Active:            58844 kB
Inactive:         116100 kB
Active(anon):      34784 kB
Inactive(anon):    89620 kB
Active(file):      24060 kB
Inactive(file):    26480 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:       3334140 kB
SwapFree:        3215756 kB
Dirty:                16 kB
Writeback:             0 kB
AnonPages:        121128 kB
Mapped:            15072 kB
Shmem:                 4 kB
Slab:              22668 kB
SReclaimable:       8028 kB
SUnreclaim:        14640 kB
KernelStack:        2016 kB
PageTables:         2532 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     3841868 kB
Committed_AS:     380460 kB
VmallocTotal:   34359738367 kB
VmallocUsed:           0 kB
VmallocChunk:          0 kB
DirectMap4k:       14208 kB
DirectMap2M:     1034240 kB
DirectMap1G:           0 kB
28
задан 30 January 2017 в 09:50
7 ответов

Я бы попытался включить overcommit и посмотрел, поможет ли это. Похоже, что ваш процесс дает сбой внутри вызова fork, который требует столько же виртуальной памяти, сколько и исходный процесс. overcommit_memory=2 не делает ваш процесс иммунитетом к киллеру OOM, он просто предотвращает его запуск, выделяя слишком много. Другие процессы могут вызывать несвязанные ошибки выделения (например, получение смежного блока памяти), которые все равно приводят в действие убийцу ООМ и избавляют ваш процесс от него.

Альтернативно (и более того), как подсказывают некоторые комментарии, покупайте больше оперативной памяти.

.
3
ответ дан 28 November 2019 в 20:01

Для ответа на вопрос заголовка используйте oom_score_adj(ядро >=2.6.36) или для более ранних ядер (>=2.6.11) oom_adj, см. man proc

/proc/[pid]/oom_score_adj (начиная с Linux 2.6.36). Этот файл можно использовать для настройки эвристики плохого состояния, используемой для выбора того, какой процесс будет убит в условиях отсутствия памяти...

/proc/[pid]/oom_adj (начиная с Linux 2.6.11) Этот файл может быть использован для настройки оценки, используемой для выбора, какой процесс должен быть убит в ситуации отсутствия памяти (OOM)...

Есть еще много чего, что можно прочитать, но установка oom_score_adj в -1000 или oom_adj в -17 приведет к тому, чего вы хотите.

Проблема в том, что будет убит что-то еще. Возможно, лучше определить, зачем вызывается OOM, и разобраться с этим.

.
31
ответ дан 28 November 2019 в 20:01

кроме упомянутого oom_score_adj увеличения для рассматриваемого процесса (что, вероятно, не сильно поможет - это сделает менее вероятным, что процесс будет убит ПЕРВЫМ, но так как это только интенсивная память процессной системы, вероятно, не будет восстанавливаться до тех пор, пока он не будет убит в конце концов), вот несколько идей для подстройки:

  • если вы установите vm. overcommit_memory=2, также подкорректируйте vm.overcommit_ratio до 90 (или установите vm.overcommit_memory=0 - смотрите kernel overcommit docs)
  • увеличить vm. min_free_kbytes для того, чтобы всегда держать некоторую физическую оперативную память свободной и таким образом уменьшать вероятность того, что OOM должен что-то убить (но не переусердствовать, т.к. это мгновенно приведет к OOM).
  • увеличить vm. swappiness до 100 (чтобы сделать замену ядра более легкой )

Обратите внимание, что если у вас слишком мало памяти для выполнения поставленной задачи, даже если вы не используете OOM, то может (или не может) стать ВНИМАНИЕ медленным - полчаса работы (на системе с достаточным количеством оперативной памяти) могут легко занять несколько недель (когда оперативная память заменяется на замену), чтобы закончить в экстремальных случаях, или даже повесить целую ВМ. Это особенно актуально, если своп происходит на классических ротационных дисках (в отличие от SSD) из-за массивных случайных чтений/записей, которые на них стоят очень дорого

.
6
ответ дан 28 November 2019 в 20:01

Несколько мыслей (из моих комментариев выше), и ссылки на интересную информацию о вашей ситуации:

  • Рекомендую проверить, что 1) вы можете обращаться к более чем 3Гб с вашим текущим ядром и конфигурацией (& cpu) [потому что если 3Гб является лимитом для вашей системы & os, то вы его превышаете] . 2) что вы разрешаете замену и подсистема замены установлена и работает. удачи (я не буду объяснять как, так как это зависит от ваших настроек и специфики. Поисковые системы помогут). И что вы не переполняете таблицу ядра (nb из pids? или что-нибудь еще (некоторые могут быть установлены во время компиляции ядра).

  • Проверьте, что все (аппаратное обеспечение, или имитируемое vm's и т.д.) 64-битное. (см., например: https://askubuntu.com/questions/313379/i-installed-a-64-bit-os-in-a-32-bit-processor/313381 ). Подсистема cpu & host OS & vm OS & vm OS должна быть полностью 64-битной, иначе у вас не будет реальной 64-битной vm

  • Хорошо бы прочитать:

  • и наконец : http://www.oracle.com/technetwork/articles/servers-storage-dev/oom-killer-1911807.html показывает способ, как не допустить, чтобы ваш процесс стал мишенью для оом-убийцы ! ( echo -17 > /proc/PROCESSPID/oom_adj ) . Может быть подвержен изменениям, а может быть и плохо (так как система теперь не может просто убить главного преступника...) . Используйте с осторожностью. @внимание, что "oom_adj" предназначено для старых ядер, и должно быть заменено на "oom_score_adj" в более новых. Спасибо, Iain)

12
ответ дан 28 November 2019 в 20:01

Похоже, что это проблема в сочетании двух факторов:

  • Использование виртуальной машины.
  • Возможная ошибка в ядре.

Частично это одна из строк, описывающая, почему это происходит:

Mar  7 02:43:11 myhost kernel: memcheck-amd64- invoked oom-killer: gfp_mask=0x24002c2, order=0, oom_score_adj=0

Другая строка:

Mar  7 02:43:11 myhost kernel: 0 pages HighMem/MovableOnly

|The Первая строка - это маска GFP, назначенная для выделения. В основном она описывает, что ядру разрешено/не разрешено делать для выполнения этого запроса. Маска указывает на кучу стандартных флагов. Последний бит, '2', однако, указывает, что выделение памяти должно происходить из зоны HighMem.

Если вы внимательно посмотрите на вывод OOM, то увидите, что зона HighMem/Normal на самом деле не существует.

Mar  7 02:43:11 myhost kernel: Node 0 DMA: 20*4kB (UM) 17*8kB (UM) 13*16kB (M) 14*32kB (UM) 8*64kB (UM) 4*128kB (M) 4*256kB (M) 0*512kB 1*1024kB (M) 0*2048kB 0*4096kB = 3944kB
Mar  7 02:43:11 myhost kernel: Node 0 DMA32: 934*4kB (UM) 28*8kB (UM) 0*16kB 0*32kB 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 3960kB

HighMem (обычно также называемый Normal на x86_64) имеет тенденцию отображать память для зон вне стандартных диапазонов 896MiB, непосредственно доступных на 32-битных системах. На x86_64 HighMem/Normal, кажется, охватывает все страницы размером выше 3Гб.

DMA32 содержит зону, используемую для памяти, которая была бы доступна на 32-битных DMA устройствах, т.е. к ним можно обращаться с 4-х байтовыми указателями. Я считаю, что DMA предназначен для 16-битных DMA устройств.

Вообще говоря, на системах с низким объемом памяти Normal не существовало бы, учитывая, что DMA32 уже охватывает все доступные виртуальные адреса.

Причина, по которой вы убиваете OOM, заключается в том, что есть выделение памяти для зоны HighMem с 0 доступными страницами. Учитывая, что обработчик не имеет абсолютно никакого способа удовлетворить требование, чтобы эта зона имела страницы для использования путем подмены, убийства других процессов или любого другого трюка, OOM-убийца просто убивает ее.

Я полагаю, что это вызвано вздутием VM хоста при загрузке. На системах KVM есть два значения, которые вы можете установить.

  • Текущая память.
  • Доступная память.

Способ, которым это работает, заключается в том, что вы можете добавлять горячую память к вашему серверу вплоть до доступной памяти. Однако на самом деле вашей системе предоставляется текущая память.

Когда ВМ KVM загружается, она начинается с максимального объема выделяемой памяти (доступной памяти). Постепенно во время фазы загрузки системы KVM когти обратно эту память, используя его вздутие, оставив вместо этого тебя с текущими настройками памяти, которые у тебя есть.

Моя вера в то, что здесь произошло. Linode позволяет вам расширять память, давая вам гораздо больше при запуске системы.

Это означает, что в начале жизни системы существует зона Normal/HighMem. Когда гипервизор раздувает ее, нормальная зона по праву исчезает из менеджера памяти. Но я подозреваю, что установка флага, из которого можно выделить указанную зону, очищается в тот момент, когда это должно произойти. Это приводит к тому, что кернел пытается выделить из несуществующей зоны.

В терминах разрешения этого вопроса у вас есть два варианта.

  1. Поднимите это в списках рассылки кернела, чтобы посмотреть, действительно ли это ошибка, ожидаемое поведение или вообще никак не связано с тем, о чём я говорю.

  2. Request that linode set the 'available memory' on the system to be same 1GiB assignment as the 'current memory'. Таким образом, система никогда не будет вздуваться и никогда не получит Нормальную зону при загрузке, сохраняя флаг ясным. Удачи им в этом!

Вы должны быть в состоянии проверить, что это так, установив вашу собственную ВМ в KVM, доступную в 6Гб, текущую в 1Гб, и запустив ваш тест, используя то же самое ядро, чтобы увидеть, происходит ли такое поведение, которое вы видите выше. Если да, то измените "доступную" установку на 1Гб и повторите тест.

Я делаю кучу обоснованных догадок и читаю между строк, чтобы придумать этот ответ, но то, что я говорю, кажется, уже соответствует изложенным фактам.

Я предлагаю проверить мою гипотезу и дать всем нам знать результат.

.
36
ответ дан 28 November 2019 в 20:01

Краткая история - попробуйте другая версия ядра. У меня есть система, которая показывала ошибки OOM с ядрами 4.2.0-x и 4.4.0-x, но не с 3.19.0-x.

Длинная история: (не слишком долго!) У меня все еще в эксплуатации Compaq DC5000 - в настоящее время с 512 МБ ОЗУ (и некоторая его часть, например, 32–128 МБ, отведена на бортовое видео ..) В основном обслуживает NFS, у меня есть подключенный монитор. к нему, поэтому иногда я вхожу в него (Ubuntu Classic, без Unity).

Через Ubuntu HWE я долгое время работал с ядром 3.19.x; это закончилось бы заменой примерно 200-300 МБ материала, но, очевидно, это был неиспользованный материал, из-за того, что ему пришлось бы заменять его позже, насколько я мог судить, не было бы никакой активности подкачки.

Ядро 4.2.0-x, а теперь ядро ​​4.4.0-x, я могу запустить короткую запись NFS в него, только 220 МБ в своп (т.е. 1,3 ГБ свободно), и он запустит OOM, убивающий вещи. Я не буду утверждать, что это ошибка ядра или "проблема настройки" (например, резерв в 64 Мбайт, это нормально, но слишком много для системы ~ 400 Мбайт или около того?)

Никакого неуважения к тем, кто говорит, что это как-то ломается. потому что он рассчитывает использовать своп; при всем уважении вы ошибаетесь. Это будет не быстро, но я использовал 1 или 2 ГБ в своп на нескольких системах 512 МБ - 1 ГБ. Конечно, для некоторых типов программного обеспечения требуется куча ОЗУ, но в моем случае (поскольку я использую одно и то же программное обеспечение только на другом ядре) это явно не так.

0
ответ дан 28 November 2019 в 20:01

Я столкнулся с этим на виртуальной машине без подкачки 2G ram, работающей под управлением Debian Stretch (последней)

только при запуске скрипта из пользовательского cron. Тот же скрипт работал из командной строки!!

Чтобы решить эту проблему, потребовалось полное обновление buster. у stretch есть ошибка в ядре или, я полагаю, cron, устанавливающий разные ограничения памяти.

0
ответ дан 16 October 2020 в 16:59

Теги

Похожие вопросы