OOM asesino no funciona?

41

Por lo que entiendo, cuando el sistema está cerca de no tener memoria libre, el kernel debería comenzar a matar procesos para recuperar algo de memoria. Pero en mi sistema esto no sucede en absoluto.

Supongamos un script simple que solo asigna mucha más memoria que la disponible en el sistema (una matriz con millones de cadenas, por ejemplo). Si ejecuto un script como este (como usuario normal), solo obtiene toda la memoria hasta que el sistema se congela por completo (solo funciona SysRQ REISUB).

La parte extraña aquí es que cuando la computadora se congela, el LED del disco duro se enciende y permanece así hasta que la computadora se reinicia, ¡ya sea que tenga una partición de intercambio montada o no!

Entonces mis preguntas son:

  1. ¿Es este comportamiento normal? Es extraño que una aplicación ejecutada como un usuario normal pueda bloquear el sistema de esta manera ...
  2. ¿Hay alguna manera de hacer que Ubuntu simplemente elimine automáticamente esas aplicaciones cuando tienen demasiada (o la mayoría) memoria?

Información Adicional

  • Ubuntu 12.04.3
  • Kernel 3.5.0-44
  • RAM: ~ 3.7GB de 4GB (compartido con la tarjeta gráfica). * *

    $ tail -n+1 /proc/sys/vm/overcommit_*
    ==> /proc/sys/vm/overcommit_memory <==
    0
    
    ==> /proc/sys/vm/overcommit_ratio <==
    50
    
    $ cat /proc/swaps
    Filename                Type        Size    Used    Priority
    /dev/dm-1                               partition   4194300 344696  -1
    
Salem
fuente
No estoy seguro de por qué no funciona. Intenta tail -n+1 /proc/sys/vm/overcommit_*y agrega la salida. Vea aquí también: ¿Cómo configuro oom-killer?
kiri
Entonces, ¿qué está pasando con su espacio de intercambio? ¿Puedes publicar alguna salida vmstat como #vmstat 1 100 o algo así? y también muéstranos cat / etc / fstab Lo que debería suceder es que con una cierta cantidad de uso de memoria, debes comenzar a escribir para intercambiar. Los procesos de eliminación no deberían ocurrir hasta que la memoria y el espacio de intercambio estén "llenos".
j0h
pruebe también #swapon -a
j0h
@ j0h Con swap parece funcionar bien (después de un tiempo, el proceso se bloqueó con algo así Allocation failed). Pero sin intercambio simplemente congela la computadora. ¿Se supone que funciona de esta manera (solo matar cuando se usa el intercambio)?
Salem
2
Con SysRq también puede invocar OOM (SysRq + F iirc)
Lekensteyn

Respuestas:

36

De la documentación oficial/proc/sys/vm/* :

oom_kill_allocating_task

Esto habilita o deshabilita la eliminación de la tarea de activación de OOM en situaciones de falta de memoria.

Si esto se establece en cero, el asesino OOM escaneará toda la lista de tareas y seleccionará una tarea basada en la heurística para matar. Esto normalmente selecciona una tarea de acaparamiento de memoria que libera una gran cantidad de memoria cuando se mata.

Si se establece en un valor distinto de cero, el asesino OOM simplemente elimina la tarea que activó la condición de falta de memoria. Esto evita el costoso análisis de la lista de tareas.

Si se selecciona panic_on_oom, tiene prioridad sobre cualquier valor que se use en oom_kill_allocating_task.

El valor predeterminado es 0.

Con el fin de resumir, al establecer oom_kill_allocating_taskque 1, en lugar de escanear el sistema en busca de procesos para matar, que es una tarea costosa y lenta, el kernel simplemente matar el proceso que hizo que el sistema salga de memoria.

Según mis propias experiencias, cuando se activa un OOM, el núcleo no tiene más "fuerza" suficiente para realizar dicho análisis, lo que hace que el sistema sea totalmente inutilizable.

Además, sería más obvio simplemente matar la tarea que causó el problema, por lo que no entiendo por qué está configurado 0de forma predeterminada.

Para la prueba, puede escribir en el pseudo-archivo adecuado /proc/sys/vm/, que se deshará en el próximo reinicio:

echo 1 | sudo tee /proc/sys/vm/oom_kill_allocating_task

Para una solución permanente, escriba lo siguiente en /etc/sysctl.confun nuevo archivo /etc/sysctl.d/, con una .confextensión ( /etc/sysctl.d/local.confpor ejemplo):

vm.oom_kill_allocating_task = 1
Teresa e Junior
fuente
2
¿Siempre se estableció en 0 en Ubuntu? Porque recuerdo que solía matar automáticamente, pero desde algunas versiones dejó de hacerlo.
skerit
1
@skerit Esto no lo sé realmente, pero se estableció en 0 en los núcleos que usé en 2010 (Debian, Liquorix y GRML).
Teresa e Junior
"Además, sería más obvio simplemente matar la tarea que causó el problema, por lo que no entiendo por qué está configurado 0de forma predeterminada". - porque el proceso que solicitó memoria no es necesariamente el que "causó el problema". Si el proceso A acapara el 99% de la memoria del sistema, pero el proceso B, que utiliza el 0,9%, es el que desencadena el asesino OOM por mala suerte, B no "causó el problema" y no tiene sentido matar B. Tener eso, ya que la política corre el riesgo de que los procesos de baja memoria totalmente sin problemas sean eliminados por casualidad debido al uso de memoria desbocada de un proceso diferente .
Mark Amery
1
@MarkAmery El verdadero problema es que Linux, en lugar de simplemente matar el proceso necesario, comienza a agitarse como un retraso, incluso si vm.admin_reserve_kbytesse incrementa a, digamos, 128 MB . La configuración vm.oom_kill_allocating_task = 1parece aliviar el problema, realmente no lo resuelve (y Ubuntu ya se ocupa de las bombas de horquilla por defecto).
Teresa e Junior
1
Quizás más elegantesudo sysctl -w vm.oom_kill_allocating_task=1
Pablo A
9

Actualización: el error está solucionado.

La respuesta de Teresa es suficiente para solucionar el problema y es buena.

Además, he presentado un informe de error porque definitivamente es un comportamiento roto.

int_ua
fuente
No sé por qué te votaron negativamente, pero eso también me parece un error del kernel. Hoy he bloqueado un gran servidor universitario y he eliminado algunos procesos que se estaban ejecutando durante semanas ... ¡Gracias por presentar ese informe de error!
shapecatcher
77
Podría haberse solucionado en 2014, en 2018 (y 18.04) el asesino de OOM una vez más no está haciendo nada.
skerit
0

Puede probar earlyoom , un asesino OOM que opera en el espacio del usuario e intenta matar el proceso más grande en una situación OOM.

qwr
fuente
-1

En primer lugar, recomiendo la actualización a 13.10 (instalación limpia, guarde sus datos).

Si no desea actualizar, cambie vm.swappiness a 10 y si encuentra problemas con su ram, instale zRAM.

Brask
fuente
2
No fui yo quien te rechazó, pero en general, bajar vm.swappinesshace más daño que bien, incluso más en sistemas que sufren problemas de poca memoria.
Teresa e Junior
No cuando comprime el RAM primero y luego evita el uso del disco que es mucho más lento y puede hacer que su computadora se congele.
Brask
En teoría, zRAM es algo bueno, pero necesita mucha CPU y, en general, no vale la pena el costo. La memoria es generalmente mucho más barata que la electricidad. Y, en una computadora portátil, donde la actualización de la RAM es más costosa, el uso de la CPU no es deseable.
Teresa e Junior
Lo que está pidiendo es tener un sistema zRAM más estable y el cambio de intercambio hará que su sistema use más recursos de CPU, sí, pero lo que tiene es un cajero automático limitado y tiene errores con la memoria, quiere solucionar el problema, no una lección de teoría de lo que sucede cuando instala zRAM.
Brask
Está claro a partir de su pregunta que puede escribir un guión incorrecto que come más de lo que debería (y ya lo he hecho yo mismo). En una situación como esta, puede ver el script capturando gigabytes de RAM en unos segundos, y zRAM no vendrá al rescate, ya que el script nunca estará lo suficientemente satisfecho.
Teresa e Junior