O que matou meu processo e por quê?


614

Meu aplicativo é executado como um processo em segundo plano no Linux. Atualmente, ele é iniciado na linha de comando em uma janela do Terminal.

Recentemente, um usuário estava executando o aplicativo por um tempo e ele morreu misteriosamente. O texto:

Morto

estava no terminal. Isso aconteceu duas vezes. Perguntei se alguém em um terminal diferente usava o comando kill para matar o processo? Não.

Sob quais condições o Linux decidiria matar meu processo? Eu acredito que o shell exibiu "matado" porque o processo morreu após receber o sinal de matar (9). Se o Linux enviou o sinal de interrupção, deve haver uma mensagem em um log do sistema em algum lugar que explique por que ele foi morto?


23
linux matou o meu processo e registrado em / var / log / messages no RedHat
Dean Hiller

1
Veja também esta resposta em unix.stackexchange.com.
Richard

Existem 3 jogadores neste evento: (1) O processo que (causa comum) ocupa muita memória e causa a condição OOM (2) O kernel que envia o SIGKILL (sinal 9) para finalizá-lo e registra o fato em algum sistema log como /var/log/messages(3) a concha sob a qual o ran processo que é o processo que imprime a Killednotificação quando o estado de saída de waitpid(2)indica o processo filho morreu de sinal 9.
arielf

Depois de ler a resposta de @ DeanHiller, encontrei mensagens de log no Ubuntu em/var/log/syslog
Dinei

Respostas:


403

Se o usuário ou sysadmin não matou o programa, o kernel pode ter. O kernel apenas mataria um processo em circunstâncias excepcionais, como falta de recursos extrema (pense em exaustão de mem + swap).


25
Se o kernel matasse o processo, colocaria uma mensagem em um log em algum lugar?
Sbq 07/04/09

186
Acabei de escrever um programa que malloc'd memória em um loop inifite. Depois que o sistema ficou lento, "Killed" foi exibido no terminal e o processo foi encerrado. O arquivo /var/log/kern.log continha muitas informações sobre a finalização. -Obrigado pelo ponteiro.
SBQ

6
É quase definitivamente isso. Eu vi muito isso quando TAing. Muitos estudantes esqueciam de liberar seus objetos, e os aplicativos acabariam atingindo 3 GB de uso de memória virtual. Assim que atingiu esse ponto, foi morto.
Herms

8
Quando o "programa simplesmente trava", esse é o sistema operacional que está realmente matando o processo!
Bernd Jendrissek

79
Use dmesgpara ver o log do kernel: aqui encontro meus processos python mortos pelo kernel devido ao consumo extremo de memória virtual.
caneta 28/08

273

Tentar:

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

Onde -B100significa o número de linhas antes da morte acontecer.

Omitir -T no Mac OS.


6
Para sua informação, de info egrep: "egrep é o mesmo que grep -E. ... Chamada direta, pois egrep ou fgrep está obsoleto" #
Air

9
No caso de um padrão simples como 'killed process'você pode simplesmente usar em grepvez de egrepsem outras alterações. Para um padrão mais complexo, você alteraria substituir, por exemplo, egrep -i -B100 'foo|ba[rz]'por grep -E -i -B100 'foo|ba[rz]'. Esta sessão de perguntas e respostas fornece mais detalhes.
Air

2
Eu também sugiro usar dmesg -Ta fim de obter timestamps legíveis
gukoff

171

Parece um bom artigo sobre o assunto: Domando o assassino do OOM .

A essência é que o Linux supercomprometememória. Quando um processo pede mais espaço, o Linux concede esse espaço, mesmo que seja reivindicado por outro processo, supondo que ninguém realmente use toda a memória que solicita. O processo obterá uso exclusivo da memória alocada quando realmente o usar, e não quando solicitar. Isso torna a alocação rápida e pode permitir que você "trapaceie" e aloque mais memória do que realmente possui. No entanto, quando os processos começam a usar essa memória, o Linux pode perceber que foi muito generoso ao alocar memória que não possui e terá que interromper um processo para liberar algumas. O processo a ser morto é baseado em uma pontuação que leva em consideração o tempo de execução (processos de longa execução são mais seguros), uso de memória (processos gananciosos são menos seguros) e alguns outros fatores, incluindo um valor que você pode ajustar para diminuir a probabilidade de um processo ser morto. Tudo está descrito no artigo com muito mais detalhes.

Edit: E aqui está outro artigo que explica muito bem como um processo é escolhido (anotado com alguns exemplos de código do kernel). O bom disso é que ele inclui alguns comentários sobre o raciocínio por trás das várias badness()regras.


3
Eu realmente amo os links do artigo. Eu sugiro que qualquer pessoa interessada no tópico os leia - especialmente os comentários no artigo da lwn.
precisa

4
"Linux vai dar-lhe esse espaço, mesmo que é reivindicada por outro processo" Isso não é bem como funciona a memória virtual ...
Mooing Duck

1
o artigo é bastante antigo (2009) e nem todas as funcionalidades sugeridas no artigo estão na linha principal.
Alex

50

Deixe-me explicar primeiro quando e por que o OOMKiller é chamado?

Digamos que você tenha 512 MB de memória RAM + 1 GB de swap. Portanto, em teoria, sua CPU tem acesso a um total de 1,5 GB de memória virtual.

Agora, por algum tempo, tudo está funcionando bem, com 1,5 GB de memória total. Mas de repente (ou gradualmente) seu sistema começou a consumir mais e mais memória e atingiu um ponto em torno de 95% da memória total usada.

Agora diga que qualquer processo solicitou grande quantidade de memória do kernel. O kernel verifica a memória disponível e descobre que não há como alocar mais memória ao seu processo. Portanto, ele tentará liberar alguma memória chamando / invocando o OOMKiller ( http://linux-mm.org/OOM ).

OOMKiller possui seu próprio algoritmo para classificar a classificação para cada processo. Normalmente, qual processo usa mais memória torna-se a vítima a ser morta.

Onde posso encontrar registros do OOMKiller?

Normalmente no diretório / var / log. /Var/log/kern.log ou / var / log / dmesg

Espero que isso ajude você.

Algumas soluções típicas:

  1. Aumentar a memória (não trocar)
  2. Encontre os vazamentos de memória no seu programa e corrija-os
  3. Restringir a memória que qualquer processo pode consumir (por exemplo, a memória da JVM pode ser restringida usando JAVA_OPTS)
  4. Veja os logs e o google :)

17

Este é o gerenciador de memória insuficiente (OOM) do Linux . Seu processo foi selecionado devido a " danos " - uma combinação de recenteidade, tamanho de residente (memória em uso, e não apenas alocada) e outros fatores.

sudo journalctl -xb

Você verá uma mensagem como:

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

12

Como o dwc e Adam Jaskiewicz declararam, o culpado é provavelmente o OOM Killer. No entanto, a próxima pergunta a seguir é: Como evito isso?

Existem várias maneiras:

  1. Dê ao seu sistema mais memória RAM, se puder (fácil se for uma VM)
  2. Verifique se o assassino do OOM escolhe um processo diferente.
  3. Desativar o assassino OOM
  4. Escolha uma distribuição Linux que é fornecida com o OOM Killer desativado.

Eu achei (2) especialmente fácil de implementar, graças a este artigo .


2
Foi a RAM para mim. Atualizei de 2 para 4 GB de RAM e o problema desapareceu. Agora o problema está na conta: P
Gus

9

O módulo PAM para limitar recursos causou exatamente os resultados que você descreveu: Meu processo morreu misteriosamente com o texto Killed na janela do console. Nenhuma saída de log, nem no syslog nem no kern.log . O programa principal me ajudou a descobrir que, exatamente após um minuto de uso da CPU, meu processo é interrompido.


8

Uma ferramenta como systemtap (ou um rastreador) pode monitorar a lógica de transmissão de sinal do kernel e reportar. por exemplo, 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

O ifbloco de filtragem nesse script pode ser ajustado a seu gosto ou eliminado para rastrear o tráfego de sinal em todo o sistema. As causas podem ser isoladas ainda mais coletando backtraces (adicione um print_backtrace()e / ou print_ubacktrace()ao probe, para o kernel e o espaço do usuário, respectivamente).


4

Em um ambiente lsf (interativo ou não), se o aplicativo exceder a utilização de memória além de algum limite predefinido pelos administradores na fila ou a solicitação de recurso ao enviar para a fila, os processos serão eliminados para que outros usuários não sejam vítimas de um potencial fugir. Nem sempre envia um email quando o faz, dependendo de como está configurado.

Uma solução nesse caso é encontrar uma fila com recursos maiores ou definir requisitos de recursos maiores no envio.

Você também pode revisar man ulimit

Embora eu não me lembro ulimitresultando em Killedsua sido um tempo desde que eu precisava disso.


2

Tivemos problemas recorrentes no Linux no site de um cliente (Red Hat, eu acho), com o OOMKiller (killer de falta de memória) matando nosso aplicativo principal (ou seja, a razão pela qual o servidor existe) e seus processos de banco de dados.

Em cada caso, o OOMKiller simplesmente decidiu que os processos estavam usando muitos recursos ... a máquina nem estava prestes a falhar por falta de recursos. Nem o aplicativo nem o banco de dados têm problemas com vazamentos de memória (ou qualquer outro vazamento de recurso).

Eu não sou um especialista em Linux, mas preferi reunir seu algoritmo para decidir quando matar algo e o que matar é complexo. Além disso, me disseram (não posso falar sobre a precisão disso) que o OOMKiller está inserido no Kernel e você não pode simplesmente não executá-lo.


1
IIRC, OOMKiller é invocado apenas como último recurso. Acho que o sistema enviará um sinal para vários aplicativos, solicitando que eles desistam de alguns recursos antes que sejam forçados a invocar o OOMKiller. Tomar com um grão de sal, como tem sido há muito tempo ...
rmeador

1
Você simplesmente não pode executá-lo. Ele está inserido no kernel, mas há opções para ajustar como ele é executado e até quais processos provavelmente matará. É executado quando o sistema inteiro está sem memória, não quando um processo específico está usando muito. Veja minha resposta para mais detalhes.
23611 Adam Jaskiewicz

6
Não executar oomkiller é muito fácil. echo "2" > /proc/sys/vm/overcommit_memory
R .. GitHub Pare de ajudar o gelo

A Red Hat não quer permitir que ela seja alterada: sudo echo "2" > /proc/sys/vm/overcommit_memory/ proc / sys / vm / overcommit_memory: Permissão negada
Brent Faust

2
Tenteecho 2 | sudo tee /proc/sys/vm/overcommit_memory
Hypershadsy

2

No meu caso, isso estava acontecendo com um trabalhador de fila do Laravel. Os logs do sistema não mencionaram nenhum assassinato, então eu olhei mais longe e constatou-se que o trabalhador estava basicamente se matando por causa de um trabalho que excedia o limite de memória (que é definido como 128M por padrão).

Executar o trabalhador da fila --timeout=600e --memory=1024corrigiu o problema para mim.


0

O usuário tem a capacidade de matar seus próprios programas, usando kill ou Control + C, mas tenho a impressão de que não foi isso que aconteceu e que o usuário se queixou de você.

O root tem a capacidade de matar programas, é claro, mas se alguém tiver root na sua máquina e estiver matando coisas, você terá problemas maiores.

Se você não é o administrador de sistemas, o administrador de sistemas pode ter configurado cotas na CPU, RAM, uso de disco ou processos de auto-eliminação que os excedam.

Além dessas suposições, não tenho certeza sem mais informações sobre o programa.


6
CTRL-C envia um kill diferente do OP relatado (SIGINT (2), pelo que me lembro, enquanto o programa está recebendo um SIGKILL (9)).
Powerlord

0

Encontrei esse problema recentemente. Finalmente, descobri que meus processos foram interrompidos logo após a atualização do opensuse zypper ser chamada automaticamente. Para desativar a atualização do zypper, resolvi o meu problema.


Estou vendo o mesmo problema. Como você rastreou qual processo matou o seu processo? Parece que existe uma ferramenta para verificar quem envia o SIGKILL para um processo.
Howy

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.