Ubuntu se está quedando rápidamente sin RAM y mi computadora está comenzando a congelarse. ¿Qué comando resolverá esto?

73

Me sucede a menudo cuando estoy compilando software en segundo plano y de repente todo comienza a disminuir y eventualmente se congela [si no hago nada], ya que me he quedado sin RAM y espacio de intercambio.

Esta pregunta supone que tengo suficiente tiempo y recursos para abrir Gnome Terminal, buscar en mi historial y ejecutar un sudocomando.

¿Qué comando puede salvarme de tener que hacer un reinicio completo, o cualquier reinicio?

Akiva
fuente
Los comentarios no son para discusión extendida; Esta conversación se ha movido al chat .
Thomas Ward
1
Si te quedas sin espacio de intercambio, creo que tienes muy poco. Tengo 20G de espacio de intercambio en esta computadora. El punto es que te dé suficiente tiempo con un sistema utilizable para matar lo que sea que esté consumiendo tu memoria. No es algo donde solo tomas lo que usarás, sino lo que esperas que nunca uses.
JoL
1
¿Estás seguro de que tanto la RAM como el intercambio se están llenando? Si ese fuera el caso, el controlador OOM mataría su compilador y liberaría memoria (y también arruinaría su proceso de compilación). De lo contrario, creo que se está llenando, y tal vez su sistema es lento porque su intercambio está en el disco del sistema.
sudo
3
Intente reducir el número de sus compilaciones paralelas si no tiene suficiente RAM para soportarlo. Si su construcción comienza a intercambiarse, será mucho más lento. Con make, intente, -j4por ejemplo, con 4 compilaciones paralelas a la vez.
Shahbaz
1
"Alexa me ordenó 8 conciertos de carnero"

Respuestas:

84

En mi experiencia, Firefox y Chrome usan más RAM que mis primeras 7 computadoras combinadas. Probablemente más que eso, pero me estoy alejando de mi punto. Lo primero que debe hacer es cerrar su navegador . ¿Un comando?

killall -9 firefox google-chrome google-chrome-stable chromium-browser

He vinculado los navegadores más populares en un solo comando allí, pero obviamente si está ejecutando algo más (o sabe que no está usando uno de estos) simplemente modifique el comando. El killall -9 ...es el bit importante. La gente se pone insegura acerca de SIGKILL(señal número 9) pero los navegadores son extremadamente resistentes. Más que eso, terminar lentamente a través de SIGTERMsignificará que el navegador hace un montón de basura de limpieza, lo que requiere una explosión de RAM adicional, y eso es algo que no puede permitirse en esta situación.

Si no puede obtener eso en un terminal que ya se está ejecutando o en un diálogo Alt+ F2, considere cambiar a un TTY. Control+ Alt+ lo F2llevará a TTY2, lo que debería permitirle iniciar sesión (aunque puede ser lento) e incluso debería permitirle usar algo como htopdepurar el problema. No creo que me haya quedado sin RAM hasta el punto de no poder htoplevantarme.

La solución a largo plazo implica comprar más RAM, alquilarla a través de una computadora remota o no hacer lo que está haciendo actualmente. Te dejaré los intrincados argumentos económicos, pero en general, la RAM es barata de comprar, pero si solo necesitas una cantidad de ráfaga, un servidor VPS facturado por minuto u hora es una buena opción.

Oli
fuente
Los comentarios no son para discusión extendida; Esta conversación se ha movido al chat .
Thomas Ward
Tengo un par de comandos vinculados a mi propio lazygitcomando que uso de vez en cuando, ¿tal vez algo así podría aplicarse aquí? Todo el killall ...guión podría reducirse a algo simple emptyramo algo así
Francisco Presencia, el
No necesita ejecutar el comando completo si sabe qué navegador se está ejecutando y supongo que la mayoría de las personas que pueden identificar una escasez de RAM lo hacen. Por extensión, me resultaría más difícil recordar que había escrito un emptyramguión que simplemente pinchar killall -9 firefox.
Oli
2
Comprando RAM ... ¿por qué no simplemente descargar más RAM?
Stephan Bijzitter
1
Bueno, es posible que bromees, pero si necesitas hacer algo por un corto tiempo que necesita mucha más RAM y CPU que el que tienes, alquilar un VPS por minuto es bastante económico para los one-shots.
Oli
66

En un sistema con la tecla de solicitud del sistema mágico habilitada, presionar Alt + System Request+ f(si no está marcado en su teclado, a System Requestmenudo está en la Print Screentecla) invocará manualmente el asesino sin memoria del núcleo (oomkiller), que intenta elegir el peor proceso ofensivo para uso de memoria y matarlo. Puede hacer esto si tiene quizás menos tiempo del que ha descrito y el sistema está a punto de comenzar (o tal vez ya ha comenzado) a sacudirse, en cuyo caso probablemente no le importe exactamente lo que se mata, solo que termine con un sistema utilizable. A veces, esto puede terminar matando a X, pero la mayoría de las veces en estos días es mucho mejor elegir un mal proceso de lo que solía ser.

Muzer
fuente
55
@ T.Sar, si vas directamente a la paliza, ya pierdes o tienes la oportunidad de matar a un devorador de memoria. No ganas nada si simplemente te abstienes de actuar.
Ruslan
44
@Muzer esto sólo funcionará cuando haya ajustado kernel.sysrqa 1o un número que incluye el bit correcto en su /etc/sysctl.d/10-magic-sysrq.conf.
Ruslan
9
@ T.Sar No vas a perder tu progreso si estás usando un sistema de construcción sensato. Retendrá todos los archivos de objetos, excepto el que estaba compilando, y luego volverá a casi donde lo dejó.
Muzer
3
@ T.Sar Solo porque lo que estás compilando no es cuerdo no significa que el sistema de compilación no sea cuerdo. Los sistemas de compilación desde tiempos inmemoriales han almacenado archivos de objetos para su reutilización en compilaciones posteriores. Por otro lado, ciertamente puedo nombrar muchos proyectos de software con menos cordura que Linux (que generalmente está bastante bien diseñado). Por ejemplo, compilando algo como Firefox u OpenOffice con 8 hilos de compilación paralelos, puedo verlo fácilmente en el orden de gigabytes de RAM. También hay muchos sistemas corporativos monolíticos que dependen de cientos de bibliotecas.
Muzer
77
@ T.Sar Linux no es realmente complejo desde el punto de vista del compilador. En realidad, apenas hay programas en C que lo sean. ¿Qué hay de C ++? ¿Alguna vez has intentado construir un programa usando Eigen o Boost? Te sorprendería la cantidad de memoria que el compilador a veces come con tales programas, y no tienen que ser complejos por sí mismos.
Ruslan
20

Al contrario de otras respuestas, sugiero que desactive el intercambio mientras lo hace. Si bien el intercambio mantiene su sistema funcionando de manera predecible, y a menudo se usa para aumentar el rendimiento de las aplicaciones que acceden al disco (al desalojar las páginas no utilizadas para dejar espacio para el caché del disco), en este caso parece que su sistema se está ralentizando a niveles inutilizables porque se está desalojando por la fuerza demasiada memoria utilizada activamente para intercambiar.

Recomendaría deshabilitar el intercambio por completo mientras realiza esta tarea, para que el asesino sin memoria actúe tan pronto como la RAM se llene.

Soluciones alternativas:

  • Aumente la velocidad de lectura del intercambio colocando su partición de intercambio en RAID1
    • O RAID0 si te sientes arriesgado, pero eso reducirá una gran cantidad de programas en ejecución si alguno de tus discos funciona mal.
  • Disminuya el número de trabajos de compilación simultáneos ("más núcleos = más velocidad", decimos todos, olvidando que se necesita un costo lineal en la RAM)
  • Esto podría ir en ambos sentidos, pero intente habilitarlo zswapen el núcleo. Esto comprime las páginas antes de enviarlas al intercambio, lo que puede proporcionar suficiente margen de maniobra para acelerar su máquina. Por otro lado, podría terminar siendo un obstáculo con la compresión / descompresión adicional que hace.
  • Rechace las optimizaciones o use un compilador diferente. La optimización del código a veces puede ocupar varios gigabytes de memoria. Si tiene LTO activado, también usará mucha RAM en la etapa de enlace. Si todo lo demás falla, puede intentar compilar su proyecto con un compilador más liviano (p tcc. Ej. ), A expensas de un ligero impacto en el rendimiento del producto compilado. (Esto generalmente es aceptable si lo hace con fines de desarrollo / depuración).
Score_Under
fuente
66
Si ha desactivado el intercambio, ese es el comportamiento de Linux cuando se queda sin memoria. Si Linux no invoca al asesino de falta de memoria, sino que se congela, eso podría significar que hay problemas más profundos con la configuración. Por supuesto, si el intercambio está activado, el comportamiento es ligeramente diferente.
Score_Under
10
@ Akiva ¿Alguna vez lo has intentado sin cambiar? Esta respuesta es acertada. Me gustaría agregar que la ejecución sudo swapoff -apuede ahorrarle cuando ya está en un aprieto: inmediatamente detendrá cualquier uso adicional de espacio de intercambio, es decir, se debe invocar el asesino OOM en el siguiente instante y poner la máquina en funcionamiento. sudo swapoff -aTambién es una excelente medida de precaución al depurar fugas de memoria o compilar, por ejemplo, Firefox. Normalmente, el intercambio es un poco útil (por ejemplo, para la hibernación o el intercambio de cosas realmente innecesarias), pero cuando realmente está utilizando la memoria, las congelaciones son peores.
Jonas Schäfer
2
@Score_Under: Se supone que las particiones de intercambio separadas en cada disco son significativamente más eficientes que el intercambio en un dispositivo md raid0. Olvidé dónde leí eso. El wiki RAID de Linux recomienda particiones separadas sobre raid0, pero no dice nada muy sólido sobre por qué es mejor . De todos modos, sí, RAID1 o RAID10n2 tiene sentido para el intercambio, especialmente si en su mayoría solo desea poder intercambiar algunas páginas sucias pero muy frías para dejar más RAM para el caché de páginas. es decir, el rendimiento de intercambio no es gran cosa.
Peter Cordes
2
Mi punto es que siguiendo su consejo, es posible que uno no pueda ejecutar esos programas en absoluto, porque necesitan intercambio. Una compilación que falla el 100% del tiempo es peor que una compilación que tiene un 50% de posibilidades de bloquear el sistema, ¿no es así?
Dmitry Grigoryev
2
Sin intercambio, en muchas máquinas es imposible compilar grandes porciones de código. ¿Por qué asumirías que es la compilación lo que quiere sacrificar?
David Schwartz el
14

Puede usar el siguiente comando (repetidamente si es necesario) para eliminar el proceso utilizando la mayor cantidad de RAM en su sistema:

ps -eo pid --no-headers --sort=-%mem | head -1 | xargs kill -9

Con:

  • ps -eo pid --no-headers --sort=-%mem: muestra los identificadores de proceso de todos los procesos en ejecución, ordenados por uso de memoria
  • head -1: solo mantenga la primera línea (proceso que utiliza la mayor cantidad de memoria)
  • xargs kill -9: matar el proceso

Edite después del comentario exacto de Dmitry:

Esta es una solución rápida y sucia que debe ejecutarse cuando no hay tareas sensibles en ejecución (tareas que no desea kill -9).

Gohu
fuente
55
Esto es mucho peor que dejar que el asesino de OOM maneje la situación. El asesino OOM es mucho más inteligente que eso. ¿Realmente ejecutas dichos comandos en una computadora con compilaciones continuas?
Dmitry Grigoryev
@DmitryGrigoryev es muy inteligente matar a Xorg a veces en mi escritorio. En los núcleos modernos, OOMK parece haber ganado algo de cordura, pero realmente no confiaría en eso después de todo eso.
Ruslan
11

Antes de ejecutar sus comandos que consumen recursos, también puede usar la llamada al sistema setrlimit (2) , probablemente con la ulimitconstrucción de su shell bash (o la limitconstrucción en zsh) notablemente con -vfor RLIMIT_AS. Entonces demasiado grande virtual consumo de espacio de direcciones (por ejemplo, con mmap (2) o sbrk (2) utilizado por malloc (3) ) fallará (con errno (3) siendo ENOMEM).

Luego, (es decir, los procesos hambrientos en su shell, después de escribir ulimit) se terminarían antes de congelar su sistema.

Lea también Linux Ate My RAM y considere deshabilitar el sobrecompromiso de memoria (ejecutando el comando echo 0 > /proc/sys/vm/overcommit_memory como root, consulte proc (5) ...).

Basile Starynkevitch
fuente
11

esto me sucede a menudo cuando estoy compilando software en segundo plano

En ese caso, algo así como "killall -9 make" (o lo que sea que esté utilizando para administrar su compilación, si no make). Esto detendrá la compilación y continuará, SIGHUP todos los procesos del compilador iniciados desde allí (con suerte haciendo que se detengan también) y, como beneficio adicional, no necesita sudo asumiendo que está compilando como el mismo usuario con el que inició sesión en como. Y dado que mata la causa real de su problema en lugar de su navegador web, sesión X o algún proceso al azar, no interferirá con cualquier otra cosa que estaba haciendo en el sistema en ese momento.

pelusa
fuente
2
Es una pena que haya tenido que desplazarme tanto para encontrar esta respuesta. Esperaba que alguien propusiera una forma de suspender el progreso en este comedor RAM.
TOOGAM
OP no se acerca a la respuesta que espera OP, pero responde a la pregunta literaria: mi máquina de basura se vuelve inutilizable cuando la construyo, deja de construir en la máquina de basura.
9ilsdx 9rvj 0lo
9

Crea un intercambio más para ti.

Lo siguiente agregará 8G de intercambio:

dd if=/dev/zero of=/root/moreswap bs=1M count=8192
mkswap /root/moreswap
swapon /root/moreswap

Seguirá siendo lento (está intercambiando) pero en realidad no debería quedarse sin nada. Las versiones modernas de Linux pueden cambiarse a archivos. El único uso para una partición de intercambio en estos días es para hibernar su computadora portátil.

William Hay
fuente
1
Tengo este método implementado como un script, en realidad, aquí . Muy útil para agregar swap sobre la marcha.
Sergiy Kolodyazhnyy
77
Por lo general, algunos intercambios son sabios, pero asignar grandes cantidades simplemente permite que la máquina golpee más antes de que el asesino OOM intervenga y elija un voluntario. El viejo papel del pulgar sobre "duplicar tu carnero como intercambio" está muerto hace mucho tiempo. Personalmente, no veo ningún valor en asignar más de ~ 1 GB de intercambio total.
Criggie
55
Con ext4, puede en fallocate -l 8G /root/moreswaplugar de ddevitar tener que hacer 8GB de E / S mientras el sistema se agita. Sin embargo, esto no funciona con ningún otro sistema de archivos. Definitivamente no XFS, donde swapon ve extensiones no escritas como agujeros. (Supongo que esta discusión de la lista de correo xfs no funcionó). Vea también swapd, un demonio que crea / elimina archivos de intercambio sobre la marcha para ahorrar espacio en disco. También askubuntu.com/questions/905668/…
Peter Cordes
1
@Criggie "Personalmente no veo ningún valor en la asignación de más de ~ 1 GB de intercambio total" - ¿Has intentado construir Firefox?
Dmitry Grigoryev
1
@ Akiva La última vez que lo verifiqué, la configuración de compilación recomendada fue de 16 GB de RAM. El archivo ejecutable principal ( xul.dll) tiene alrededor de 50 MB, por lo que es aproximadamente 10 veces más pesado que el kernel de Linux.
Dmitry Grigoryev
5

Una forma de obtener una porción de RAM libre en un corto plazo es usar zram , que crea un disco RAM comprimido y se intercambia allí. Con cualquier CPU medio decente, esto es mucho más rápido que el intercambio normal, y las tasas de compresión son bastante altas con muchos dispositivos RAM modernos como los navegadores web.

Suponiendo que tiene zram instalado y configurado, todo lo que tiene que hacer es ejecutar

sudo service zramswap start
Dmitry Grigoryev
fuente
¿Funciona en todos los sistemas de archivos como btrfs?
Akiva
1
@Akiva zram nunca toca el disco, por lo que diría que sí;)
Dmitry Grigoryev
3

sudo swapoff -adesactivará el intercambio, haciendo que el kernel elimine automáticamente el proceso con la puntuación más alta si el sistema se queda sin memoria. Lo uso si sé que estaré ejecutando algo pesado en RAM que preferiría matar si se sale de control antes que dejar que se intercambie y se quede atascado para siempre. Use sudo swapon -apara volver a habilitarlo después.

Más tarde, es posible que desee echar un vistazo a su configuración de intercambio. Parece que su intercambio está en el mismo disco que la partición raíz, lo que ralentizaría su sistema cuando presiona el intercambio, así que evítelo si puede. Además, en mi opinión, los sistemas modernos a menudo se configuran con demasiado intercambio. 32GiB RAM generalmente significa que el intercambio de 32GiB se asigna de manera predeterminada, como si realmente quisiera poner 32GiB en su espacio de intercambio.

sudo
fuente
Oh, acabo de ver que alguien comentó eso en alguna parte.
sudo
3

Otra cosa que se podría hacer es liberar la memoria caché de la página a través de este comando:

echo 3 | sudo tee /proc/sys/vm/drop_caches

De la documentación de kernel.org (énfasis agregado):

drop_caches

Escribir esto hará que el kernel deje caer cachés limpias, así como objetos de losas recuperables como dentries e inodes. Una vez caídos, su memoria se vuelve libre .

Para liberar caché de página: echo 1> / proc / sys / vm / drop_caches Para liberar objetos de losa recuperables (incluye dentries e inodes): echo 2> / proc / sys / vm / drop_caches Para liberar objetos de losa y pagecache: echo 3> / proc / sys / vm / drop_caches

Esta es una operación no destructiva y no liberará ningún objeto sucio. Para aumentar el número de objetos liberados por esta operación, el usuario puede ejecutar 'sync' antes de escribir en / proc / sys / vm / drop_caches. Esto minimizará la cantidad de objetos sucios en el sistema y creará más candidatos para descartar.

Sergiy Kolodyazhnyy
fuente
Interesante ... ¿te importaría explicar esa lógica de comando?
Akiva
1
@Akiva básicamente le dice al kernel de Linux que libere la RAM. Esto no elimina la causa, que está acabando con el proceso ofensivo, por lo que la respuesta de Oli es la solución al problema. Dejar caer cachés evitará que su sistema se quede sin memoria, por lo tanto, evitará que se congele, lo que le dará tiempo para resolver el problema real. Esto probablemente será un poco más rápido que hacer un archivo de intercambio, especialmente si está en el disco duro y no en SSD
Sergiy Kolodyazhnyy
77
El caché es lo primero que debe ir cuando llena la memoria, por lo que no creo que esto ayude mucho. De hecho, no creo que este comando tenga un uso práctico fuera de la depuración del comportamiento del núcleo o de las optimizaciones de acceso al disco de tiempo. Recomiendo humildemente no ejecutar este comando en cualquier sistema que necesite más rendimiento.
Score_Under
2
@Score_Under - "El caché es lo primero que debe ir cuando llena la memoria" - bueno, eso depende de su configuración /proc/sys/vm/swappiness. Con swappiness establecido en 0, tienes razón. Con la configuración predeterminada de 60, estás cerca. Sin embargo, si se establece en 200, serán las páginas menos utilizadas recientemente de los procesos en ejecución las que se descartan primero ... en ese caso particular, este comando puede ser útil. Sin embargo, establecer un intercambio a 0 (o algún valor bajo, tal vez 20 o 30) sería un mejor enfoque general.
Julio
3
@Score_Under Este comando fue útil en núcleos antiguos con kswapderror (algunas personas incluso crearon cronjobs con él). Pero tienes razón, dudo que ayude con esta pregunta.
Dmitry Grigoryev
1

Dijiste "compilando en el fondo". ¿Qué haces en primer plano? Si está desarrollando con Eclipse u otro IDE pesado de recursos, verifique si todo está correctamente terminado en la consola.

Los entornos de desarrollo a menudo permiten iniciar múltiples procesos en desarrollo, estos pueden permanecer bloqueados también después de que ya no esté interesado en ellos (en el depurador, o simplemente no se haya terminado correctamente). Si el desarrollador no presta atención, se pueden acumular decenas de procesos olvidados durante el día, utilizando múltiples gigabytes juntos.

Verifique si todo lo que debería terminarse en IDE está terminado.

h22
fuente