OOM killer no funciona correctamente, conduce a un sistema operativo congelado

23

Durante años, el asesino OOM de mi sistema operativo no funciona correctamente y conduce a un sistema congelado.
Cuando el uso de la memoria es muy alto, todo el sistema tiende a "congelarse" (de hecho: se vuelve extremadamente lento) durante horas o incluso días , en lugar de matar procesos para liberar la memoria.
El máximo que he registrado es de 7 días antes de resignarme a operar un reinicio.
Cuando la OOM está a punto de alcanzarse, el iowait es muy alto (~ 70%), antes de volverse incalculable.
La herramienta: iotopha demostrado que todos los programas están leyendo a un rendimiento muy alto (por decenas de MB / seg) de mi disco duro.
¿Qué están leyendo esos programas?
- La jerarquía de directorios?
- El código ejecutable en sí?
No exactamente ahora.

[editado] En el momento en que escribí este mensaje (en 2017) estaba usando un ArchLinux actualizado (4.9.27-1-lts), pero ya había experimentado el problema durante años antes.
He experimentado el mismo problema con varias distribuciones de Linux y diferentes configuraciones de hardware.
Actualmente (2019), estoy usando un Debian 9.6 (4.9.0) actualizado. Tengo 16 GB de RAM física, un SSD en el que está instalado mi sistema operativo y ninguna partición de intercambio .

Debido a la cantidad de RAM que tengo, no quiero habilitar una partición de intercambio, ya que solo retrasaría la aparición del problema.
Además, el intercambio de SSD con demasiada frecuencia podría reducir potencialmente la vida útil del disco.
Por cierto, ya lo he intentado con y sin una partición de intercambio, se ha demostrado que solo retrasa la aparición del problema, pero no es la solución.

Para mí, el problema es causado por el hecho de que Linux elimina datos esenciales de los cachés , lo que lleva a un sistema congelado porque tiene que leer todo, cada vez desde el disco duro.

Incluso me pregunto si Linux no eliminaría las páginas de códigos ejecutables de los programas en ejecución, lo que explicaría por qué los programas que normalmente no leen una gran cantidad de datos, se comportan de esta manera en esta situación.

He intentado varias cosas con la esperanza de solucionar este problema.
Una era establecerla /proc/sys/vm/min_free_kbytesen 1000000(1 GB).
Debido a que este 1 GB debería permanecer libre, pensé que Linux reservaría esta memoria para almacenar en caché datos importantes.
Pero no ha funcionado.

Además, creo útil agregar que, incluso si en teoría pudiera sonar genial, restringir el tamaño de la memoria virtual al tamaño de la memoria física, al definir /proc/sys/vm/overcommit_memoryque 2no es decentemente técnicamente posible en mi situación, porque el tipo de aplicaciones que uso, requieren más memoria virtual de la que usan efectivamente por algunas razones.
Según el archivo /proc/meminfo, el Commited_ASvalor suele ser mayor que el doble de RAM física en mi sistema (16 GB, Commited_AS suele ser> 32 GB).

He experimentado este problema con /proc/sys/vm/overcommit_memorysu valor predeterminado: 0y durante un tiempo lo he definido como: 1porque prefiero que el asesino OOM elimine los programas en lugar de comportarse incorrectamente porque no verifican los valores de retorno de malloccuando se rechazan las asignaciones.

Cuando hablaba de este problema en IRC , conocí a otros usuarios de Linux que han experimentado este mismo problema, por lo que supongo que muchos usuarios están preocupados por esto.
Para mí, esto no es aceptable ya que incluso Windows trata mejor con un uso elevado de memoria.

Si necesita más información, tiene una sugerencia, por favor dígame.

Documentación:
https://en.wikipedia.org/wiki/Thrashing_%28computer_science%29
https://en.wikipedia.org/wiki/Memory_overcommitment
https://www.kernel.org/doc/Documentation/sysctl/vm. txt
https://www.kernel.org/doc/Documentation/vm/overcommit-accounting
https://lwn.net/Articles/317814/

Hablan sobre esto:
¿Por qué el asesino de falta de memoria de Linux (OOM) no se ejecuta automáticamente, sino que funciona con sysrq-key?
¿Por qué el asesino OOM a veces no puede matar a los cerdos de recursos?
Precargando el OOM Killer
¿Es posible activar el OOM-killer en un intercambio forzado?
¿Cómo evitar una alta latencia cerca de la situación de OOM?
https://lwn.net/Articles/104179/
https://bbs.archlinux.org/viewtopic.php?id=233843

M89
fuente
1
Creo que esto es lo que debe esperar, si está agitando, pero realmente no se está acercando al 100% "usado", es decir, hay demasiado uso de memoria que está respaldado por archivos, contados como "buff / cache". (Ugh, esta redacción supone que sus asignaciones tmpfs son triviales, ya que se muestran como "buff / cache", pero no se pueden paginar a un sistema de archivos físico). min_free_kbytesno es relevante, no es una reserva para páginas en caché. AFAICT ninguno de los sistemas vm permite reservar memoria específicamente para páginas en caché, es decir, limitar las asignaciones MAP_ANONYMOUS :(.
sourcejedi
2
He estado buscando una solución para este problema exacto durante años sin ningún éxito. Creo que noté el problema por primera vez después de reemplazar mi HDD por un SSD, lo que también me impidió desactivar el intercambio por completo, pero realmente no puedo garantizar que nunca haya sucedido antes de estos cambios, por lo que podría no estar relacionado. Estoy en Archlinux por cierto.
brunocodutra
2
Acabo de publicar en los foros de Arch Linux sobre esto.
Ignat Insarov
1
@ dsstorefile1 Gracias, lo intentaré. Pero, ¿cómo podría desencadenar el asesino OOM con seguridad cuando el núcleo en esta situación no puede hacerlo correctamente?
M89
1
Ayudó cuando Chrome logró filtrar toda mi RAM ... (aunque finalmente agregué una partición de intercambio de disco real y finalmente actualicé a una cantidad decente de RAM)
Gert van den Berg

Respuestas:

5

He encontrado dos explicaciones (de la misma cosa) de por qué kswapd0 hace la lectura de disco constante ocurre mucho antes de OOM-asesino mata el proceso infractor:

  1. vea la respuesta y el comentario de esta respuesta de askubuntu SE
  2. vea la respuesta y los comentarios de David Schwartz sobre esta respuesta en unix SE

Citaré aquí el comentario de 1. que realmente me abrió los ojos sobre por qué recibía una lectura constante del disco mientras todo estaba congelado :

Por ejemplo, considere un caso en el que tiene cero intercambio y el sistema casi se está quedando sin RAM. El núcleo tomará memoria de, por ejemplo, Firefox (puede hacer esto porque Firefox está ejecutando código ejecutable que se ha cargado desde el disco; el código se puede cargar desde el disco nuevamente si es necesario). Si Firefox necesita acceder a esa RAM nuevamente N segundos más tarde, la CPU genera un "fallo" que obliga a Linux a liberar algo de RAM (por ejemplo, tomar algo de RAM de otro proceso), cargar los datos faltantes del disco y luego permitir que Firefox continúe como usual. Esto es bastante similar al intercambio normal y kswapd0 lo hace. - Mikko Rantalainen 15 de febrero a las 13:08

Si alguien tiene una manera de cómo deshabilitar este comportamiento (¿quizás recompilar el núcleo con qué opciones? ), ¡Hágamelo saber lo antes posible! Muy apreciado, gracias!

ACTUALIZACIÓN: La única forma que he encontrado hasta ahora es parcheando el kernel, y funciona para mí con swap deshabilitado (es decir CONFIG_SWAP is not set), pero no funciona para otros con swap habilitado parece ; Vea el parche dentro de esta pregunta.


fuente
Por favor, retire el texto que no es válido. No etiquete las ediciones con "EDITAR" en el texto. Son obvios en el historial de revisiones .
Kusalananda
1
@Kusalananda Se debe alentar a este usuario, ya que probablemente él fue el que más contribuyó.
M89
@Kusalananda Pensé que era importante mantenerlos para que otros pudieran ver qué (más) se intentó y no funcionó. ¿Quizás en UPDATEvez de EDIThubiera sido mejor?
@MarcusLinsner No, lo siento, has entendido mal. Mostrando lo que ha intentado es lo que se hace cuando se pide una pregunta. La respuesta debe ser correcta para la pregunta tal como se plantea actualmente. Quiero decir, una edición incluso le pide al lector que ignore las ediciones anteriores . Si está interesado en ver el historial de edición, puede verlo aquí .
Kusalananda
0

El memory.minparámetro en el cgroups-v2controlador de memoria debería ayudar.

A saber, déjame citar:

Protección de memoria dura. Si el uso de memoria de un cgroup está dentro de su límite mínimo efectivo, la memoria del cgroup no se recuperará bajo ninguna circunstancia. Si no hay memoria recuperable sin protección disponible, se invoca el asesino OOM.

Fuente: https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html

Vladimir Nikishkin
fuente
¿Podría elaborar por favor? Su respuesta se queda un poco corta al responder la pregunta de OP.
Paradoja