El asesino de habitaciones generalmente tiene mala reputación entre los usuarios de Linux. Esto puede ser parte de la razón por la que Linux lo invoca sólo cuando no tiene otra opción. Cambiará el entorno de escritorio, eliminará toda la caché de la página y vaciará cada búfer antes de que finalmente finalice un proceso. Al menos eso es lo que creo que hará. Todavía tengo que tener la paciencia suficiente para esperarlo, sentado frente a un sistema que no responde.
Esto hizo que otras personas y yo nos preguntaramos si el oom-killer podría configurarse para intervenir antes: reddit r/linux, superuser.com, unix.stackexchange.com.
Resulta que no, no puede. Al menos usando el asesino del núcleo. En el espacio de usuario, sin embargo, podemos hacer lo que queramos.
earlyoom quiere ser simple y sólido. Está escrito en C puro sin dependencias. Un extenso conjunto de pruebas (pruebas unitarias y de integración) está escrito en Go.
earlyoom comprueba la cantidad de memoria disponible y el intercambio libre hasta 10 veces por segundo (con menos frecuencia si hay mucha memoria libre). De forma predeterminada, si ambos están por debajo del 10%, eliminará el proceso más grande ( oom_score
más alto). El valor porcentual se puede configurar mediante argumentos de la línea de comando.
En el resultado free -m
siguiente, la memoria disponible es 2170 MiB y el intercambio libre es 231 MiB.
total used free shared buff/cache available Mem: 7842 4523 137 841 3182 2170 Swap: 1023 792 231
¿Por qué se comprueba la memoria "disponible" en lugar de la memoria "libre"? En un sistema Linux saludable, se supone que la memoria "libre" es cercana a cero, porque Linux utiliza toda la memoria física disponible para el acceso al disco en caché. Estos cachés se pueden eliminar cada vez que se necesite la memoria para otra cosa.
La memoria "disponible" se encarga de ello. Resume toda la memoria que no se utiliza o que se puede liberar inmediatamente.
Tenga en cuenta que necesita una versión reciente free
y el kernel de Linux 3.14+ para ver la columna "disponible". Si tiene un kernel reciente, pero una versión antigua de free
, puede obtener el valor de grep MemAvailable /proc/meminfo
.
Cuando tanto la memoria disponible como el intercambio libre caen por debajo del 10% de la memoria total disponible para los procesos del espacio de usuario (=total-compartido), enviará la señal SIGTERM
al proceso que utiliza la mayor cantidad de memoria en opinión del núcleo ( /proc/*/oom_score
).
nohang, un proyecto similar a earlyoom, escrito en Python y con características y opciones de configuración adicionales.
Los parches del kernel de información de bloqueo de presión (psi) de Facebook y el asistente de espacio de usuario oomd que lo acompaña. Los parches están fusionados en Linux 4.20.
earlyoom no usa echo f > /proc/sysrq-trigger
porque:
En algunas versiones del kernel (probadas en v4.0.5), activar manualmente el kernel oom killer no funciona en absoluto. Es decir, es posible que solo libere algo de memoria gráfica (que se asignará nuevamente inmediatamente) y no elimine ningún proceso. Aquí puede ver cómo se ve esto en mi máquina (gráficos integrados Intel).
Este problema se solucionó en Linux v5.17 (commit f530243a).
Al igual que lo haría el kernel de Linux, earlyoom encuentra a su víctima leyendo /proc/*/oom_score
.
Aproximadamente 2 MiB
( VmRSS
), aunque sólo 220 kiB
son memoria privada ( RssAnon
). El resto es la biblioteca libc ( RssFile
) que se comparte con otros procesos. Toda la memoria se bloquea usando mlockall()
para garantizar que earlyoom no se ralentice en situaciones de poca memoria.
Compilarse usted mismo es fácil:
clon de git https://github.com/rfjakob/earlyoom.gitcd earlyoom hacer
Opcional: ejecute las autopruebas integradas:
hacer prueba
Inicie earlyoom automáticamente registrándolo como servicio:
sudo make install # systemdsudo make install-initscript # no-systemd
Tenga en cuenta que para sistemas con SELinux deshabilitado (Ubuntu 19.04, Debian 9...) las advertencias de chcon que informan que no se pudo establecer el contexto se pueden ignorar de forma segura.
Para Debian 10+ y Ubuntu 18.04+, hay un paquete Debian:
sudo apt instalar earlyoom
Para Fedora y RHEL 8 con EPEL, existe un paquete Fedora:
sudo dnf instalar earlyoom sudo systemctl enable --ahora temprano
Para Arch Linux, existe un paquete Arch Linux:
sudo pacman -S tempranooom sudo systemctl enable --ahora temprano
Disponibilidad en otras distribuciones: ver página de repología.
Simplemente inicie el ejecutable que acaba de compilar:
./earlyoom
Le informará cuánta memoria y swap tiene, cuál es el mínimo, cuánta memoria está disponible y cuánto swap está libre.
./earlyoom eearlyoom v1.8 mem total: 23890 MiB, user mem total: 21701 MiB, swap total: 8191 MiB sending SIGTERM when mem avail <= 10.00% and swap free <= 10.00%, SIGKILL when mem avail <= 5.00% and swap free <= 5.00% mem avail: 20012 of 21701 MiB (92.22%), swap free: 5251 of 8191 MiB (64.11%) mem avail: 20031 of 21721 MiB (92.22%), swap free: 5251 of 8191 MiB (64.11%) mem avail: 20033 of 21723 MiB (92.22%), swap free: 5251 of 8191 MiB (64.11%) [...]
Si los valores caen por debajo del mínimo, los procesos se cancelan hasta que vuelven a estar por encima del mínimo. Cada acción se registra en stderr. Si está ejecutando earlyoom como un servicio systemd, puede ver las últimas 10 líneas usando
estado systemctl temprano
Para ver earlyoom
en acción, cree/simule una pérdida de memoria y deje que earlyoom
haga lo que hace:
tail /dev/zero
Si necesita realizar más acciones después de que earlyoom
finalice un proceso (como enviar correos electrónicos), puede analizar los registros de la siguiente manera:
sudo journalctl -u earlyoom | grep sending
El resultado de ejemplo para el comando de prueba anterior ( tail /dev/zero
) se verá así:
Feb 20 10:59:34 debian earlyoom[10231]: sending SIGTERM to process 7378 uid 1000 "tail": oom_score 156, VmRSS 4962 MiB
Para versiones anteriores de
earlyoom
, utilice:sudo journalctl -u earlyoom | grep -iE "(sending|killing)"
Desde la versión 1.6, earlyoom puede enviar notificaciones sobre procesos cancelados a través del sistema d-bus. Pase -n
para habilitarlos.
Para ver realmente las notificaciones en su sesión de GUI, necesita tener systembus-notify ejecutándose como su usuario.
Además, earlyoom puede ejecutar un script para cada proceso finalizado, proporcionando información sobre el proceso a través de las variables de entorno EARLYOOM_PID
, EARLYOOM_UID
y EARLYOOM_NAME
. Pase -N /path/to/script
para habilitar.
Advertencia: en el caso del modo de ejecución en seco, el script se ejecutará en rápida sucesión; asegúrese de tener implementado algún tipo de límite de velocidad.
La bandera de línea de comando --prefer
especifica los procesos que prefieren matar; Asimismo, --avoid
especifica procesos para evitar la muerte. Consulte https://github.com/rfjakob/earlyoom/blob/master/MANPAGE.md#--prefer-regex para obtener más detalles.
Si está ejecutando earlyoom como un servicio del sistema (a través de systemd o init.d), puede ajustar su configuración a través del archivo proporcionado en /etc/default/earlyoom
. El archivo ya contiene algunos ejemplos en los comentarios, que puede utilizar para crear su propio conjunto de configuración basado en las opciones de línea de comando admitidas, por ejemplo:
EARLYOOM_ARGS="-m 5 -r 60 --avoid '(^|/)(init|Xorg|ssh)$' --prefer '(^|/)(java|chromium)$'"
Después de ajustar el archivo, simplemente reinicie el servicio para aplicar los cambios. Por ejemplo, para systemd:
systemctl reiniciar temprano
Tenga en cuenta que este archivo de configuración no tiene ningún efecto en las instancias de earlyoom fuera de systemd/init.d.
earlyoom v1.8 Usage: ./earlyoom [OPTION]... -m PERCENT[,KILL_PERCENT] set available memory minimum to PERCENT of total (default 10 %). earlyoom sends SIGTERM once below PERCENT, then SIGKILL once below KILL_PERCENT (default PERCENT/2). -s PERCENT[,KILL_PERCENT] set free swap minimum to PERCENT of total (default 10 %). Note: both memory and swap must be below minimum for earlyoom to act. -M SIZE[,KILL_SIZE] set available memory minimum to SIZE KiB -S SIZE[,KILL_SIZE] set free swap minimum to SIZE KiB -n enable d-bus notifications -N /PATH/TO/SCRIPT call script after oom kill -g kill all processes within a process group -d, --debug enable debugging messages -v print version information and exit -r INTERVAL memory report interval in seconds (default 1), set to 0 to disable completely -p set niceness of earlyoom to -20 and oom_score_adj to -100 --ignore-root-user do not kill processes owned by root --sort-by-rss find process with the largest rss (default oom_score) --prefer REGEX prefer to kill processes matching REGEX --avoid REGEX avoid killing processes matching REGEX --ignore REGEX ignore processes matching REGEX --dryrun dry run (do not kill any processes) --syslog use syslog instead of std streams -h, --help this help text
Consulte la página de manual para obtener más detalles.
Los informes de errores y las solicitudes de extracción son bienvenidos a través de github. En particular, me alegro de aceptar
Informes de casos de uso y comentarios
No usamos procps/libproc2 porque procps_pids_select(), por alguna razón, siempre analiza /proc/$pid/status. Esto es relativamente caro y no lo necesitamos.
v1.8.2, 2024-05-07
Agregue process_mrelease
a las llamadas al sistema permitidas (compromiso)
Reparar la sintaxis IPAddressDeny
(compromiso)
Permitir -p
(confirmar)
Correcciones en el archivo de unidad systemd earlyoom.service
v1.8.1, 2024-04-17
Corregir fallas de prueba triviales causadas por la reformulación de mensajes (compromiso)
v1.8, 2024-04-15
Introduzca user mem total
/ meminfo_t.UserMemTotal
y calcule MemAvailablePercent en función de él (confirmar, más información en la página de manual)
Utilice process_mrelease
(#266)
Soporte NO_COLOR
(https://no-color.org/)
No se deje confundir por procesos con un hilo principal zombie (commit)
Agregue --sort-by-rss
, ¡gracias @RanHuang! Esto seleccionará un proceso para eliminar ACC. al RSS más grande en lugar del oom_score más grande.
El conjunto de pruebas Gitlab CI ahora también se ejecuta en Amazon Linux 2 y Oracle Linux 7.
v1.7, 2022-03-05
Agregue el indicador -N
para ejecutar un script cada vez que se finaliza un proceso (confirmación, sección de la página de manual)
Agregue el indicador -g
para eliminar todo el grupo de procesos (#247)
Elimine el indicador -i
(ignorado por compatibilidad), no funciona correctamente en los kernels de Linux 5.9+ (#234)
Endurecimiento: elimine las capacidades ambientales al iniciar (#234)
v1.6.2, 2020-10-14
Verificar nuevamente la situación de la memoria antes de matar a la víctima (comprometerse)
Nunca terminarnos a nosotros mismos (#205)
Vuelca el buffer en el error de conversión /proc/meminfo (#214)
1.6.1, 2020-07-07
Limpiar procesos zombies de dbus-send (#200)
Saltar procesos con oom_score_adj=-1000 (210)
1.6, 2020-04-11
-n
/ -N
ahora habilita la nueva lógica
Debe tener systembus-notify ejecutándose en su sesión de GUI para recibir notificaciones de trabajo.
Reemplace la antigua lógica de notificación de la GUI notify-send
con dbus-send
/ systembus-notify (#183)
Manejar /proc
montado con hidepid con gracia (problema #184)
v1.5, 2020-03-22
-p
: establece oom_score_adj en -100
en lugar de -1000
(#170)
Permitir el uso de -M
y -m
, y -S
y -s
. Se utilizará el valor más bajo (convertido a porcentajes).
Establezca el intervalo de informe de memoria en earlyoom.default
en 1 hora en lugar de 1 minuto (#177)
v1.4, 2020-03-01
Utilice variables locales de bloque siempre que sea posible
Introduzca PATH_LEN para reemplazar varias longitudes de búfer codificadas
Haga que la lógica de selección de víctimas sea un 50 % más rápida mediante la carga diferida de atributos del proceso
Registre el ID de usuario uid
de los procesos eliminados además del pid y el nombre.
Registro de depuración de color en gris claro
limpieza de código
Ampliar el conjunto de pruebas ( make test
)
Ejecute cppcheck
cuando esté disponible
Agregar puntos de referencia de pruebas unitarias ( make bench
)
Eliminar privilegios de root en el archivo de unidad systemd earlyoom.service
v1.3.1, 2020-02-27
Solucionar fallos falsos del conjunto de pruebas en sistemas con mucha RAM (problema n.º 156)
v1.3, 2019-05-26
No salga con un error fatal si el límite SIGTERM <límite SIGKILL
Permitir límite cero SIGKILL
Esto soluciona el problema de que a veces earlyoom mata más de un proceso cuando uno sería suficiente (problema n.º 121).
Espere a que los procesos realmente salgan al enviar una señal
Sea más liberal en los límites aceptados para SIGTERM y SIGKILL (número 97)
Vuelva a formatear la salida de inicio para dejar en claro que AMBOS swap y mem deben ser <= límite
Agregue el script auxiliar notify_all_users.py
Agregue CODE_OF_CONDUCT.md (Pacto del colaborador 1.4) (#102)
Corregir nombres de aplicaciones UTF8 posiblemente truncados en la salida del registro (#110)
v1.2, 2018-10-28
Implemente un tiempo de suspensión adaptativo (= tasa de sondeo adaptativa) para reducir aún más el uso de la CPU (problema n.º 61)
Elimine la opción para usar kernel oom-killer ( -k
, ahora ignorado por compatibilidad) (problema #80)
Manejar con gracia el caso de que se agregue o elimine un intercambio después de que se inició earlyoom (problema 62, confirmación)
Implementar eliminación por etapas: primero SIGTERM, luego SIGKILL, con límites configurables (problema n.° 67)
v1.1, 2018-07-07
Corregir posible inyección de código shell a través de notificaciones GUI (compromiso)
Si no se puede finalizar algún proceso, solo duerma 1 segundo en lugar de 10 (problema n.° 74)
Envíe la notificación GUI después de matar, no antes (problema n.° 73)
Aceptar --help
además de -h
Corrija el nombre de proceso incorrecto en el registro y en la notificación de finalización (compromiso 1, compromiso 2, problema n.° 52, problema n.° 65, problema n.° 194)
Arreglar la posible división por cero con -S
(compromiso)
v1.0, 2018-01-28
Agregue las opciones --prefer
y --avoid
(@TomJohnZ)
Agregue soporte para notificaciones GUI, agregue opciones -n
y -N
v0.12: Agregar opciones -M
y -S
(@nailgun); agregar página de manual, parametrizar Makefile (@yangfl)
v0.11: Se corrige el comportamiento indefinido en get_entry_fatal (falta retorno, confirmación)
v0.10: Permitir anular la variable VERSIÓN de Makefile para facilitar el empaquetado, agregar la opción de línea de comando -v
v0.9: si oom_score de todos los procesos es 0, use VmRss para encontrar una víctima
v0.8: Utilice una estimación si el kernel no proporciona MemAvailable
v0.7: seleccione la víctima mediante oom_score en lugar de VmRSS, agregue las opciones -i
y -d
v0.6: Agregar opciones de línea de comandos -m
, -s
, -k
v0.5: Agregar soporte de intercambio
v0.4: agregue el script de inicio SysV (gracias @joeytwiddle), use el nuevo MemAvailable
de /proc/meminfo
(necesita Linux 3.14+, confirmación)
v0.2: Agregar archivo de unidad systemd
v0.1: versión inicial