¿Qué mató mi proceso y por qué?

614

Mi aplicación se ejecuta como un proceso en segundo plano en Linux. Actualmente se inicia en la línea de comando en una ventana de Terminal.

Recientemente, un usuario estaba ejecutando la aplicación por un tiempo y murió misteriosamente. El texto:

Delicado

Estaba en la terminal. Esto sucedió dos veces. Pregunté si alguien en una Terminal diferente usó el comando kill para matar el proceso. No.

¿En qué condiciones Linux decidiría matar mi proceso? Creo que el caparazón se mostró "asesinado" porque el proceso murió después de recibir la señal de matar (9). Si Linux envió la señal de apagado, ¿debería haber un mensaje en un registro del sistema en algún lugar que explique por qué fue eliminado?

sbq
fuente
23
Linux eliminó mi proceso y lo registró en / var / log / messages en redhat
Dean Hiller
1
Consulte también esta respuesta en unix.stackexchange.com.
Richard
Hay 3 jugadores en este evento: (1) El proceso que (causa común) toma demasiada memoria y causa la condición OOM (2) El núcleo que envía el SIGKILL (señal 9) para terminarlo y registra el hecho en algún sistema log like /var/log/messages(3) El shell bajo el cual se ejecutó el proceso, que es el proceso que imprime la Killednotificación cuando el estado de salida waitpid(2)indica que el proceso secundario murió por la señal 9.
arielf
Después de leer la respuesta de @ DeanHiller, encontré mensajes de registro en Ubuntu en/var/log/syslog
Dinei

Respuestas:

403

Si el usuario o el administrador del sistema no mataron el programa que el kernel puede tener. El kernel solo mataría un proceso en circunstancias excepcionales, como la falta de recursos extrema (piense en mem + agotamiento de intercambio).

dwc
fuente
25
Si el núcleo matara el proceso, ¿pondría un mensaje en un registro en alguna parte?
sbq
186
Acabo de escribir un programa que malloca la memoria en un bucle infinito. Después de que el sistema se ralentizó, se visualizó "Killed" en el terminal y el proceso finalizó. El archivo /var/log/kern.log contenía mucha información sobre la terminación. -Gracias por la anotación.
sbq
66
Eso es casi definitivamente eso. Vi esto mucho cuando TAing. Muchos estudiantes se olvidarían de liberar sus objetos, y las aplicaciones eventualmente alcanzarían 3GB de uso de memoria virtual. Tan pronto como llegó a ese punto, fue asesinado.
Herms
8
Cuando el "programa simplemente falla", ¡ese es el sistema operativo que realmente está matando el proceso!
Bernd Jendrissek
79
Utilícelo dmesgpara ver el registro del kernel: aquí encuentro mis procesos de python eliminados por el kernel debido al consumo extremo de memoria virtual.
caneta
273

Tratar:

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

Donde -B100significa el número de líneas antes de que ocurriera la muerte.

Omitir -T en Mac OS.

Ravindranath Akila
fuente
66
Para su información, desde info egrep: "egrep es lo mismo que grep -E ... invocación directa, ya sea como egrep o fgrep está en desuso."
Aire
99
En el caso de un patrón simple como el 'killed process'que puede usar en greplugar de egrepsin otros cambios. Para un patrón más complejo, cambiaría reemplazar, por ejemplo, egrep -i -B100 'foo|ba[rz]'con grep -E -i -B100 'foo|ba[rz]'. Este Q&A da más detalles.
Aire
2
También sugiero usar dmesg -Tpara obtener marcas de tiempo legibles
gukoff el
171

Esto parece un buen artículo sobre el tema: domar al asesino OOM .

La esencia es que Linux compromete demasiadomemoria. Cuando un proceso solicita más espacio, Linux le dará ese espacio, incluso si es reclamado por otro proceso, bajo el supuesto de que nadie realmente usa toda la memoria que solicita. El proceso obtendrá un uso exclusivo de la memoria que ha asignado cuando realmente lo usa, no cuando lo solicita. Esto hace que la asignación sea rápida y puede permitirle "engañar" y asignar más memoria de la que realmente tiene. Sin embargo, una vez que los procesos comiencen a usar esta memoria, Linux podría darse cuenta de que ha sido demasiado generoso al asignar memoria que no tiene, y tendrá que eliminar un proceso para liberar algo. El proceso que debe eliminarse se basa en una puntuación que tiene en cuenta el tiempo de ejecución (los procesos de ejecución prolongada son más seguros), el uso de memoria (los procesos codiciosos son menos seguros) y algunos otros factores, incluido un valor que puede ajustar para hacer que un proceso sea menos probable que se elimine. Todo se describe en el artículo con mucho más detalle.

Editar: Y aquí hay otro artículo que explica bastante bien cómo se elige un proceso (anotado con algunos ejemplos de código de kernel). Lo bueno de esto es que incluye algunos comentarios sobre el razonamiento detrás de las diversas badness()reglas.

Adam Jaskiewicz
fuente
3
Realmente me encantan los enlaces del artículo. Sugeriría a cualquiera que esté interesado en el tema que los lea, especialmente los comentarios sobre el artículo de lwn.
Jon Bringhurst
44
"Linux le dará ese espacio, incluso si es reclamado por otro proceso" Así no es exactamente cómo funciona la memoria virtual ...
Mooing Duck
1
el artículo es bastante antiguo (2009) y no todas las funcionalidades sugeridas en el artículo están en la línea principal.
Alex
50

Permítanme explicar primero cuándo y por qué se invoca a OOMKiller.

Digamos que tiene 512 RAM + 1GB de memoria de intercambio. Entonces, en teoría, su CPU tiene acceso a un total de 1.5GB de memoria virtual.

Ahora, durante algún tiempo, todo funciona bien dentro de 1,5 GB de memoria total. Pero de repente (o gradualmente) su sistema ha comenzado a consumir más y más memoria y alcanzó un punto en torno al 95% de la memoria total utilizada.

Ahora supongamos que cualquier proceso ha solicitado una gran cantidad de memoria del núcleo. Kernel verifica la memoria disponible y descubre que no hay forma de que pueda asignar más memoria a tu proceso. Por lo tanto, intentará liberar memoria invocando / invocando OOMKiller ( http://linux-mm.org/OOM ).

OOMKiller tiene su propio algoritmo para calificar el rango de cada proceso. Por lo general, qué proceso usa más memoria se convierte en la víctima a matar.

¿Dónde puedo encontrar registros de OOMKiller?

Típicamente en el directorio / var / log. /Var/log/kern.log o / var / log / dmesg

Espero que esto te ayudará.

Algunas soluciones típicas:

  1. Aumentar la memoria (no cambiar)
  2. Encuentra las pérdidas de memoria en tu programa y arréglalas
  3. Restrinja la memoria que cualquier proceso puede consumir (por ejemplo, la memoria JVM puede restringirse usando JAVA_OPTS)
  4. Ver los registros y google :)
Jadav Bheda
fuente
17

Este es el administrador de Linux sin memoria (OOM) . Su proceso fue seleccionado debido a ' maldad ': una combinación de actualidad, tamaño de residente (memoria en uso, en lugar de solo asignada) y otros factores.

sudo journalctl -xb

Verás un mensaje 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
mikemaccana
fuente
12

Como dwc y Adam Jaskiewicz han declarado, el culpable es probablemente el Asesino OOM. Sin embargo, la siguiente pregunta que sigue es: ¿Cómo evito esto?

Hay varias formas:

  1. Dele a su sistema más RAM si puede (fácil si es una VM)
  2. Asegúrese de que el asesino de OOM elija un proceso diferente.
  3. Deshabilitar el asesino OOM
  4. Elija una distribución de Linux que se envíe con el OOM Killer deshabilitado.

Descubrí que (2) es especialmente fácil de implementar, gracias a este artículo .

Carl
fuente
2
Fue la RAM para mí. Actualicé de 2 a 4 GB de RAM y el problema desapareció. Ahora el problema es con la factura: P
Gus
9

El módulo PAM para limitar los recursos causó exactamente los resultados que describió: mi proceso murió misteriosamente con el texto Asesinado en la ventana de la consola. No hay salida de registro, ni en syslog ni en kern.log . El programa superior me ayudó a descubrir que exactamente después de un minuto de uso de la CPU, mi proceso se anula.

Christian Ammer
fuente
8

Una herramienta como systemtap (o un trazador) puede monitorear la lógica de transmisión de señal del núcleo e informar. por ejemplo, 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

El ifbloque de filtrado en ese script puede ajustarse al gusto o eliminarse para rastrear el tráfico de señal en todo el sistema. Las causas pueden aislarse aún más mediante la recopilación de trazas inversas (agregue ay print_backtrace()/ o print_ubacktrace()a la sonda, para el núcleo y el espacio de usuario, respectivamente).

fche
fuente
4

En un entorno lsf (interactivo o de otro tipo) si la aplicación excede la utilización de la memoria más allá de un umbral preestablecido por los administradores en la cola o la solicitud de recursos al enviar a la cola, los procesos serán eliminados para que otros usuarios no sean víctimas de un potencial huir. No siempre envía un correo electrónico cuando lo hace, dependiendo de cómo esté configurado.

Una solución en este caso es encontrar una cola con recursos más grandes o definir requisitos de recursos más grandes en el envío.

Es posible que también desee revisar man ulimit

Aunque no recuerdo haber ulimitresultado en que Killedhaya pasado un tiempo desde que lo necesitaba.

anciano
fuente
2

Hemos tenido problemas recurrentes bajo Linux en el sitio de un cliente (Red Hat, creo), con OOMKiller (asesino sin memoria) matando tanto nuestra aplicación principal (es decir, la razón por la que existe el servidor) como sus procesos de base de datos.

En cada caso, OOMKiller simplemente decidió que los procesos usaban muchos recursos ... la máquina ni siquiera estaba a punto de fallar por falta de recursos. Ni la aplicación ni su base de datos tienen problemas con pérdidas de memoria (o cualquier otra pérdida de recursos).

No soy un experto en Linux, pero más bien reuní su algoritmo para decidir cuándo matar algo y qué matar es complejo. Además, me dijeron (no puedo hablar de la precisión de esto) que OOMKiller está integrado en el Kernel y que no se puede simplemente no ejecutarlo.

Lawrence Dol
fuente
1
IIRC, OOMKiller solo se invoca como último recurso. Creo que el sistema incluso enviará una señal a varias aplicaciones pidiéndoles que renuncien amablemente a algunos recursos antes de verse obligado a invocar a OOMKiller. Tomar con un grano de sal, ya que ha pasado mucho tiempo ...
rmeador
1
Usted puede simplemente no ejecutarlo. Está integrado en el núcleo, pero hay opciones para ajustar cómo funciona, e incluso qué procesos es probable que mate. Se ejecuta cuando todo el sistema no tiene memoria, no cuando un proceso específico está usando demasiado. Vea mi respuesta para más detalles.
Adam Jaskiewicz el
66
No ejecutar oomkiller es bastante fácil. echo "2" > /proc/sys/vm/overcommit_memory
R .. GitHub DEJA DE AYUDAR AL HIELO
Red Hat no quiere permitir que se cambie: sudo echo "2" > /proc/sys/vm/overcommit_memory/ proc / sys / vm / overcommit_memory: Permiso denegado
Brent Faust
2
Probarecho 2 | sudo tee /proc/sys/vm/overcommit_memory
Hypershadsy
2

En mi caso, esto estaba sucediendo con un trabajador de cola Laravel. Los registros del sistema no mencionaron ningún asesinato, así que busqué más y resultó que el trabajador básicamente se estaba suicidando debido a un trabajo que excedía el límite de memoria (que está configurado en 128M por defecto).

Ejecutando el trabajador de cola con --timeout=600y --memory=1024solucionó el problema para mí.

iSWORD
fuente
0

El usuario tiene la capacidad de matar sus propios programas, usando kill o Control + C, pero tengo la impresión de que no es lo que sucedió, y que el usuario se quejó a usted.

root tiene la capacidad de matar programas, por supuesto, pero si alguien tiene root en su máquina y está matando cosas, tiene mayores problemas.

Si no es el administrador del sistema, el administrador del sistema puede haber configurado cuotas en la CPU, la RAM, el uso del disco ort y los procesos de eliminación automática que los superan.

Aparte de esas conjeturas, no estoy seguro sin más información sobre el programa.

Tom Ritter
fuente
66
CTRL-C envía un asesinato diferente al OP informado (SIGINT (2) como recuerdo, mientras que el programa está recibiendo un SIGKILL (9)).
Powerlord el
0

Encontré este problema últimamente. Finalmente, descubrí que mis procesos se interrumpieron justo después de que se llamara automáticamente a la actualización de Opensuse zypper. Para deshabilitar la actualización de zypper resolvió mi problema.

pobre desarrollador
fuente
Estoy viendo el mismo problema. ¿Cómo rastreaste qué proceso mató tu proceso? Parece que hay una herramienta para verificar quién envía SIGKILL a un proceso.
Howy
0

Resolvió este problema aumentando el tamaño del intercambio :

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

Lejla
fuente
3
No publique respuestas de solo enlace a otras preguntas de Stack Exchange. En su lugar, incluya las partes esenciales de la respuesta aquí y adapte la respuesta a esta pregunta específica.
doble pitido