Cosa ha ucciso il mio processo e perché?


614

La mia applicazione funziona come processo in background su Linux. Attualmente è avviato dalla riga di comando in una finestra Terminale.

Recentemente un utente ha eseguito l'applicazione per un po 'ed è morta misteriosamente. Il testo:

Ucciso

era sul terminal. Questo è successo due volte. Ho chiesto se qualcuno in un Terminale diverso ha usato il comando kill per terminare il processo? No.

In quali condizioni Linux deciderebbe di interrompere il mio processo? Credo che la shell abbia mostrato "ucciso" perché il processo è morto dopo aver ricevuto il segnale kill (9). Se Linux ha inviato il segnale di interruzione dovrebbe esserci un messaggio nel registro di sistema da qualche parte che spiega perché è stato ucciso?


23
Linux ha interrotto il mio processo e lo ha registrato in / var / log / messages su redhat
Dean Hiller,

1
Vedi anche questa risposta su unix.stackexchange.com.
Richard,

Ci sono 3 giocatori in questo evento: (1) Il processo che (causa comune) occupa troppa memoria e causa la condizione OOM (2) Il kernel che invia il SIGKILL (segnale 9) per terminarlo e registra il fatto in qualche sistema log like /var/log/messages(3) La shell in cui è stato eseguito il processo che è il processo che stampa la Killednotifica quando lo stato di uscita da waitpid(2)indica che il processo figlio è morto dal segnale 9.
arielf

Dopo aver letto la risposta di @DeanHiller, ho trovato i messaggi di log su Ubuntu sotto/var/log/syslog
Dinei, il

Risposte:


403

Se l'utente o l'amministratore di sistema non hanno ucciso il programma, il kernel potrebbe avere. Il kernel ucciderebbe un processo solo in circostanze eccezionali come la fame estrema di risorse (pensate a esaurimento mem + swap).


25
Se il kernel uccidesse il processo metterebbe un messaggio in un registro da qualche parte?
sbq,

186
Ho appena scritto un programma che mallocava la memoria in un ciclo infinito. Dopo che il sistema si è rallentato, "Killed" è stato visualizzato nel terminale e il processo è stato terminato. Il file /var/log/kern.log conteneva molte informazioni sulla risoluzione. -Grazie per il puntatore.
sbq,

6
È quasi sicuramente. L'ho visto molto durante il TAing. Molti studenti dimenticheranno di liberare i loro oggetti e le app alla fine raggiungerebbero 3 GB di utilizzo della memoria virtuale. Non appena ha colpito quel punto è stato ucciso.
Herms,

8
Quando il "programma semplicemente si arresta in modo anomalo", questo è il sistema operativo che effettivamente uccide il processo!
Bernd Jendrissek,

79
Usa dmesgper vedere il registro del kernel: qui trovo i miei processi Python uccisi dal kernel a causa dell'estremo consumo di memoria virtuale.
Caneta,

273

Provare:

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

Dove -B100indica il numero di righe prima dell'uccisione.

Ometti -T su Mac OS.


6
Cordiali saluti, da info egrep: "egrep è lo stesso di grep -E. ... L'invocazione diretta di egrep o fgrep è deprecata"
Air

9
Nel caso di un modello semplice come quello 'killed process'che puoi usare, grepinvece di egrepsenza altre modifiche. Per uno schema più complesso, cambieresti sostituisci ad es . egrep -i -B100 'foo|ba[rz]'Con grep -E -i -B100 'foo|ba[rz]'. Queste domande e risposte forniscono maggiori dettagli.
Air

2
Suggerirei anche di utilizzare dmesg -Tper ottenere timestamp leggibili
gukoff

171

Sembra un buon articolo sull'argomento: domare il killer OOM .

L'essenza è che Linux sovraccaricamemoria. Quando un processo richiede più spazio, Linux gli darà quello spazio, anche se è rivendicato da un altro processo, partendo dal presupposto che nessuno utilizza effettivamente tutta la memoria richiesta. Il processo otterrà l'uso esclusivo della memoria che ha allocato quando lo utilizza effettivamente, non quando lo richiede. Ciò rende l'allocazione rapida e potrebbe consentire di "imbrogliare" e allocare più memoria di quanta ne abbiate realmente. Tuttavia, una volta che i processi iniziano a utilizzare questa memoria, Linux potrebbe rendersi conto che è stato troppo generoso nell'allocare la memoria che non ha, e dovrà interrompere un processo per liberarne un po '. Il processo da uccidere si basa su un punteggio che tiene conto del runtime (i processi di lunga durata sono più sicuri), dell'utilizzo della memoria (i processi più avidi sono meno sicuri) e di alcuni altri fattori, incluso un valore che puoi regolare per rendere meno probabile che un processo venga ucciso. È tutto descritto nell'articolo in modo molto più dettagliato.

Modifica: Ed ecco un altro articolo che spiega abbastanza bene come viene scelto un processo (annotato con alcuni esempi di codice del kernel). Il bello di questo è che include alcuni commenti sul ragionamento alla base delle varie badness()regole.


3
Adoro i collegamenti agli articoli. Suggerirei a chiunque sia interessato all'argomento di leggerli, in particolare i commenti sull'articolo lwn.
Jon Bringhurst,

4
"Linux gli darà quello spazio, anche se è rivendicato da un altro processo" Non è così che funziona la memoria virtuale ...
Mooing Duck

1
l'articolo è piuttosto vecchio (2009) e non tutte le funzionalità suggerite nell'articolo sono in linea di principio.
Alex,

50

Vorrei prima spiegare quando e perché OOMKiller viene invocato?

Supponi di avere 512 RAM + 1GB di memoria di scambio. Quindi, in teoria, la tua CPU ha accesso a un totale di 1,5 GB di memoria virtuale.

Ora, per qualche tempo, tutto funziona benissimo entro 1,5 GB di memoria totale. Ma all'improvviso (o gradualmente) il tuo sistema ha iniziato a consumare sempre più memoria e ha raggiunto circa il 95% della memoria totale utilizzata.

Ora supponiamo che qualsiasi processo abbia richiesto un grosso pezzo di memoria dal kernel. Il kernel controlla la memoria disponibile e scopre che non è possibile allocare più memoria al processo. Quindi tenterà di liberare un po 'di memoria chiamando / invocando OOMKiller ( http://linux-mm.org/OOM ).

OOMKiller ha il suo algoritmo per assegnare un punteggio a ogni processo. In genere, quale processo utilizza più memoria diventa la vittima da uccidere.

Dove posso trovare i registri di OOMKiller?

Tipicamente nella directory / var / log. /Var/log/kern.log o / var / log / dmesg

Spero che questo ti possa aiutare.

Alcune soluzioni tipiche:

  1. Aumenta la memoria (non scambia)
  2. Trova le perdite di memoria nel tuo programma e correggili
  3. Limitare la memoria che può essere utilizzata da qualsiasi processo (ad esempio la memoria JVM può essere limitata utilizzando JAVA_OPTS)
  4. Vedi i registri e google :)

17

Questo è il Linux out of memory manager (OOM) . Il tuo processo è stato selezionato a causa della " cattiveria ", una combinazione di novità, dimensione del residente (memoria in uso, piuttosto che allocata) e altri fattori.

sudo journalctl -xb

Vedrai un messaggio come:

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

Come hanno affermato dwc e Adam Jaskiewicz, il colpevole è probabilmente il killer OOM. Tuttavia, la domanda successiva che segue è: come posso impedirlo?

Esistono diversi modi:

  1. Dai al tuo sistema più RAM se puoi (facile se è una VM)
  2. Assicurati che il killer OOM scelga un processo diverso.
  3. Disabilita OOM Killer
  4. Scegli una distro Linux fornita con OOM Killer disabilitato.

Ho trovato (2) particolarmente facile da implementare, grazie a questo articolo .


2
Era la RAM per me. Ho aggiornato da 2 a 4 GB di RAM e il problema è andato. Ora il problema è con il conto: P
Gus

9

Il modulo PAM per limitare le risorse ha causato esattamente i risultati che hai descritto: Il mio processo è morto misteriosamente con il testo Killed nella finestra della console. Nessun output del log, né in syslog né in kern.log . Il programma principale mi ha aiutato a scoprire che esattamente dopo un minuto di utilizzo della CPU il mio processo viene interrotto.


8

Uno strumento come systemtap (o un tracciante) può monitorare la logica e la trasmissione del segnale del kernel. ad esempio, 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

Il ifblocco di filtro in quello script può essere regolato a piacere o eliminato per tracciare il traffico del segnale a livello di sistema. Le cause possono essere ulteriormente isolate raccogliendo backtrace (aggiungere a print_backtrace()e / o print_ubacktrace()al probe, rispettivamente per kernel e spazio utente).


4

In un ambiente lsf (interattivo o di altro tipo) se l'applicazione supera l'utilizzo della memoria oltre una certa soglia preimpostata da parte degli amministratori sulla coda o la richiesta di risorse nel presentare alla coda i processi verranno uccisi in modo che altri utenti non cadano vittima di un potenziale scappa. Non sempre invia un'e-mail quando lo fa, a seconda di come è impostato.

Una soluzione in questo caso è trovare una coda con risorse più grandi o definire requisiti di risorse più grandi nell'invio.

Potresti anche voler rivedere man ulimit

Anche se non ricordo di averlo ulimitottenuto è Killedpassato un po 'di tempo da quando ne avevo bisogno.


2

Abbiamo avuto problemi ricorrenti sotto Linux presso un sito del cliente (Red Hat, credo), con OOMKiller (killer di memoria insufficiente) che uccide sia la nostra applicazione principale (ovvero il motivo per cui esiste il server) sia i suoi processi di base di dati.

In ogni caso OOMKiller ha semplicemente deciso che i processi stavano usando molte risorse ... la macchina non stava nemmeno per fallire per mancanza di risorse. Né l'applicazione né il database presentano problemi con perdite di memoria (o qualsiasi altra perdita di risorse).

Non sono un esperto di Linux, ma ho piuttosto raccolto il suo algoritmo per decidere quando uccidere qualcosa e cosa uccidere è complesso. Inoltre, mi è stato detto (non posso parlare dell'accuratezza di questo) che OOMKiller è inserito nel kernel e non puoi semplicemente non eseguirlo.


1
IIRC, OOMKiller viene invocato solo come ultima risorsa. Penso che il sistema invierà persino un segnale a varie app chiedendo loro di rinunciare gentilmente ad alcune risorse prima che sia costretto a invocare OOMKiller. Prendi con un po 'di sale, dato che è passato molto tempo ...
rmeador,

1
Non puoi semplicemente eseguirlo. È inserito nel kernel, ma ci sono opzioni per ottimizzare il modo in cui viene eseguito e anche quali processi è probabile che uccida. Funziona quando l'intero sistema ha esaurito la memoria, non quando un processo specifico sta usando troppo. Vedi la mia risposta per maggiori dettagli.
Adam Jaskiewicz,

6
Non eseguire oomkiller è abbastanza facile. echo "2" > /proc/sys/vm/overcommit_memory
R .. GitHub smette di aiutare ICE il

Red Hat non vuole consentirne la modifica: sudo echo "2" > /proc/sys/vm/overcommit_memory/ proc / sys / vm / overcommit_memory: autorizzazione negata
Brent Faust

2
Provaecho 2 | sudo tee /proc/sys/vm/overcommit_memory
Hypershadsy,

2

Nel mio caso questo stava accadendo con un lavoratore in coda Laravel. I registri di sistema non menzionavano alcun omicidio, quindi ho guardato oltre e si è scoperto che il lavoratore si stava praticamente uccidendo a causa di un lavoro che superava il limite di memoria (che è impostato su 128 M per impostazione predefinita).

Eseguire il gestore delle code con --timeout=600e --memory=1024risolvere il problema per me.


0

L'utente ha la possibilità di uccidere i propri programmi, usando kill o Control + C, ma ho l'impressione che non sia quello che è successo e che l'utente si è lamentato con te.

root ha la capacità di uccidere i programmi ovviamente, ma se qualcuno ha root sul tuo computer e sta uccidendo roba hai problemi più grandi.

Se non sei l'amministratore di sistema, l'amministratore di sistema potrebbe aver impostato quote su CPU, RAM, utilizzo del disco o processi automatici che li superano.

A parte queste ipotesi, non sono sicuro senza ulteriori informazioni sul programma.


6
CTRL-C manda un kill diverso rispetto all'OP riportato (SIGINT (2) come ricordo, mentre il programma sta ricevendo un SIGKILL (9)).
Powerlord,

0

Ho riscontrato questo problema ultimamente. Alla fine, ho scoperto che i miei processi sono stati interrotti subito dopo la chiamata automatica dell'aggiornamento di Opensuse zypper. Per disabilitare l'aggiornamento di Zypper ho risolto il mio problema.


Sto riscontrando lo stesso problema. Come hai rintracciato quale processo ha ucciso il tuo processo? Sembra che ci sia uno strumento per verificare chi invia SIGKILL a un processo.
Howy,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.