La computadora se congela con RAM casi llena, posiblemente un problema de caché

75

El problema creo que es algo similar a este hilo.

No importa si he habilitado o deshabilitado el intercambio, cada vez que la cantidad de RAM utilizada real comienza a acercarse al máximo y casi no queda espacio para el caché de disco, el sistema deja de responder.

El disco está girando salvajemente y, a veces, después de largas esperas de 10 a 30 minutos, se descongelará, y a veces no (o se me acabó la paciencia). A veces, si actúo rápidamente, puedo abrir lentamente la consola y eliminar algunas de las aplicaciones que comen ram, como el navegador, y el sistema se descongela casi al instante.

Debido a este problema, casi nunca veo nada en el intercambio, solo a veces hay algunos MB allí, y poco después aparece este problema. Mi conjetura no tan educada sería que está conectado de alguna manera a que la memoria caché del disco es demasiado codiciosa o que la administración de memoria es demasiado indulgente, por lo que cuando se necesita la memoria no se libera lo suficientemente rápido y priva al sistema de hambre.

El problema se puede lograr realmente rápido si se trabaja con archivos de lagrge (500 MB +) que se cargan en la memoria caché del disco y, aparentemente, el sistema no puede descargarlos lo suficientemente rápido.

Cualquier ayuda o ideas serán muy apreciadas.

Por ahora tengo que vivir con miedo constante, cuando hacer algo la computadora puede congelarse y generalmente tengo que reiniciarlo, si realmente se está quedando sin RAM, me gustaría mucho más simplemente matar algunas de las aplicaciones de espacio de usuario, como broser ( preferiblemente si de alguna manera pudiera marcar cuál matar primero)

Aunque el misterio es por qué el intercambio no me salva en esta situación.

ACTUALIZACIÓN: No se colgó durante algún tiempo, pero ahora tengo varias ocurrencias nuevamente. Ahora mantengo el monitor de memoria ram en mi pantalla en todo momento y cuando se produjo el bloqueo, todavía mostraba ~ 30% libre (probablemente usado por la caché de disco). Síntomas adicionales: si en el momento que estoy viendo el video (reproductor VLC) el sonido se detiene primero, después de unos segundos la imagen se detiene. Si bien el sonido se detuvo, todavía tengo algo de control sobre la PC, pero cuando la imagen se detiene, ya ni siquiera puedo mover el mouse, así que lo reinicié después de esperar un poco. Por cierto, esto no sucedió cuando comencé a ver el video, pero en algún momento en (20 minutos) y no hice nada más activamente en ese momento, a pesar de que el navegador y la sobre escritura estaban abiertos en la segunda pantalla todo el tiempo. Básicamente algo simplemente decide suceder en un punto y bloquea el sistema.

Según lo solicitado en los comentarios, ejecuté dmesg justo después del bloqueo. No noté nada extraño, pero no sabía qué buscar, así que aquí está: https://docs.google.com/document/d/1iQih0Ee2DwsGd3VuQZu0bPbg0JGjSOCRZhu0B05CMYs/edit?hl=en_US&authkey=CPzF7bc

Krišjānis Nesenbergs
fuente
11
Esto necesita llamar más la atención. Sé que hay errores archivados durante muchos años.
n3rd
1
@ n3rd: Este es el error .
Dan Dascalescu
@ Krišjānis Nesenbergs: Corríjame si me equivoco, al pegar un archivo largo también se cuelga.
Rick2047
Gracias por hacer esta pregunta y encontrar una solución. Agregue una fecha a la actualización, de lo contrario no está claro qué funcionó y qué no funcionó. Tengo el mismo problema, siempre estoy verificando los niveles de memoria, y tengo 16GB, planeando tener 32GB, para ver si puedo solucionarlo de esa manera ...
Beto Aveiga

Respuestas:

63

Para solucionar este problema, descubrí que necesita establecer la siguiente configuración en algo alrededor del 5% -6% de su RAM física total, dividida por la cantidad de núcleos en la computadora:

sysctl -w vm.min_free_kbytes=65536

Tenga en cuenta que esta es una configuración por núcleo, por lo que si tengo 2 GB de RAM y dos núcleos, calculé el 6% de solo 1 GB y agregué un poco más solo para estar seguro.

Esto obliga a la computadora a tratar de mantener esta cantidad de RAM libre y, al hacerlo, limita la capacidad de almacenar en caché los archivos de disco. Por supuesto, todavía intenta almacenarlos en caché e intercambiarlos de inmediato, por lo que probablemente también debería limitar su intercambio:

sysctl -w vm.swappiness=5

(100 = intercambio tan a menudo como sea posible, 0 = intercambio solo en caso de necesidad total)

El resultado es que Linux ya no decide cargar aleatoriamente un archivo de película completo de aproximadamente 1 GB en RAM mientras lo mira y mata la máquina al hacerlo.

Ahora hay suficiente espacio reservado para evitar la falta de memoria, lo que aparentemente fue el problema (ya que no hay más bloqueos como antes).

Después de probar durante un día: los bloqueos se han ido, a veces hay ralentizaciones menores, porque las cosas se almacenan en caché con más frecuencia, pero puedo vivir con eso si no tengo que reiniciar la computadora cada pocas horas.

La lección aquí es: la administración de memoria predeterminada es solo uno de los casos de uso y no siempre es la mejor, aunque algunas personas intentan sugerir lo contrario: ubuntu de entretenimiento en el hogar debe configurarse de manera diferente al servidor.


Probablemente desee hacer que estas configuraciones sean permanentes agregándolas a su /etc/sysctl.confestilo de esta manera:

vm.swappiness=5
vm.min_free_kbytes=65536
Krišjānis Nesenbergs
fuente
1
Un buen hallazgo, trate de informar de los errores de él, así que hay más conciencia sobre el tema y es de esperar que alguien va a llegar a una solución para no cargar al azar de toda la película,
Oxwivi
gracias, gran detalle y explica mi problema. ¡Muy apreciado!
odedbd
1
bueno, probé casi todo, y solo tu sugerencia mejoró las cosas. gracias
vitalii
1
Si estoy ejecutando sin una partición de intercambio, ¿debo usar una cantidad mayor que 5-6%? Y vm.swappinesssupongo que la configuración no hará nada en ese caso.
Jarett Millard
1
"[vm.min_free_kbytes] obliga a la computadora a intentar mantener esta cantidad de RAM libre y, al hacerlo, limita la capacidad de almacenar en caché los archivos de disco". - Lamento molestar, pero esto no está relacionado con lo que vm.min_free_kbyteshace. Actúa como un bloque de páginas reservadas para facilitar las __GFP_WAITasignaciones atómicas (es decir, rellenar o eliminar / no ) cuando se encuentra bajo una alta contención de memoria del sistema. De hecho, podría tener sentido plantearlo aquí (ya que probablemente estas paradas están relacionadas con la contención de la memoria del sistema), pero ciertamente no sería por la razón descrita en esta respuesta.
Chris Down
9

Esto me sucedió en una nueva instalación de Ubuntu 14.04.

En mi caso, no tenía nada que ver con los problemas de sysctl mencionados.

En cambio, el problema era que el UUID de la partición de intercambio era diferente durante la instalación que después de la instalación. Por lo tanto, mi intercambio nunca estuvo habilitado y mi máquina se bloqueó después de unas horas de uso.

La solución fue verificar el UUID actual de la partición de intercambio con

sudo blkid

y luego sudo nano /etc/fstabreemplazar el valor de UUID del intercambio incorrecto con el reportado por blkid.

Un simple reinicio para afectar los cambios, y listo.

Dale Anderson
fuente
3
Muchas gracias! He estado luchando con este error increíblemente irritante por algo cerca de un año y he intentado todo para solucionarlo. ¿Por qué Linux tiene este comportamiento? Parece que debería actuar como si no hubiera un intercambio, e invocar al asesino OOM. En cambio, parece fingir que hay un intercambio, pero luego no puede cambiar las cosas (porque en realidad no lo hay, ya que está mal configurado).
crazy2be
@ crazy2be No está fallando, está teniendo éxito sin cesar. Incluso sin ningún intercambio, Linux aún puede localizar programas y archivos no modificados en la memoria y volver a leerlos desde el disco.
Martin Thornton
5

Sé que esta pregunta es antigua, pero tuve este problema en Ubuntu (Chrubuntu) 14.04 en un Chromebook Acer C720. Intenté la solución de Krišjānis Nesenbergs, y funcionó un poco, pero a veces todavía fallaba.

Finalmente encontré una solución que funcionó instalando zram en lugar de usar el intercambio físico en el SSD. Para instalarlo, simplemente seguí las instrucciones aquí , así:

sudo apt-get install zram-config

Luego pude configurar el tamaño del intercambio zram modificando /etc/init/zram-config.confen la línea 21.

20: # Calculate the memory to user for zram (1/2 of ram)
21: mem=$(((totalmem / 2 / ${NRDEVICES}) * 1024))

Reemplacé el 2 con un 1 para hacer que el tamaño de zram sea del mismo tamaño que la cantidad de ram que tengo. Desde entonces, no he tenido más bloqueos o falta de respuesta del sistema.

brismuth
fuente
zrames una opción viable solo si no puede instalar más RAM. Si el sistema es demasiado lento al cambiar a SSD y se queda sin RAM sin intercambio, entonces zrampuede ayudar un poco hasta que intente hacer un poco más y el resultado sea el mismo que sin RAM sin intercambio.
Mikko Rantalainen
5

¡Nada funcionó para mí!

Entonces escribí un script para monitorear el uso de la memoria. Primero intentará borrar la memoria caché de RAM si el consumo de memoria aumenta un umbral. Puede configurar este umbral en el script. Si el consumo de memoria no llega por debajo del umbral, incluso entonces, comenzará a eliminar procesos por uno en orden decreciente de consumo de memoria hasta que el consumo de memoria esté por debajo del umbral. Lo configuré en 96% por defecto. Puede configurarlo cambiando el valor de la variable RAM_USAGE_THRESHOLD en el script.

Estoy de acuerdo en que matar procesos que consumen mucha memoria no es la solución perfecta, ¡pero es mejor matar UNA aplicación en lugar de perder TODO el trabajo! el script le enviará una notificación de escritorio si el uso de RAM aumenta el umbral. También le notificará si mata algún proceso.

#!/usr/bin/env python
import psutil, time
import tkinter as tk
from subprocess import Popen, PIPE
import tkinter
from tkinter import messagebox
root = tkinter.Tk()
root.withdraw()

RAM_USAGE_THRESHOLD = 96
MAX_NUM_PROCESS_KILL = 100

def main():
    if psutil.virtual_memory().percent >= RAM_USAGE_THRESHOLD:
        # Clear RAM cache
        mem_warn = "Memory usage critical: {}%\nClearing RAM Cache".\
            format(psutil.virtual_memory().percent)
        print(mem_warn)
        Popen("notify-send \"{}\"".format(mem_warn), shell=True)
        print("Clearing RAM Cache")
        print(Popen('echo 1 > /proc/sys/vm/drop_caches',
                    stdout=PIPE, stderr=PIPE,
                    shell=True).communicate())
        post_cache_mssg = "Memory usage after clearing RAM cache: {}%".format(
                            psutil.virtual_memory().percent)
        Popen("notify-send \"{}\"".format(post_cache_mssg), shell=True)
        print(post_cache_mssg)

        if psutil.virtual_memory().percent < RAM_USAGE_THRESHOLD:
            print("Clearing RAM cache saved the day")
            return
        # Kill top C{MAX_NUM_PROCESS_KILL} highest memory consuming processes.
        ps_killed_notify = ""
        for i, ps in enumerate(sorted(psutil.process_iter(),
                                      key=lambda x: x.memory_percent(),
                                      reverse=True)):
            # Do not kill root
            if ps.pid == 1:
                continue
            elif (i > MAX_NUM_PROCESS_KILL) or \
                    (psutil.virtual_memory().percent < RAM_USAGE_THRESHOLD):
                messagebox.showwarning('Killed proccess - save_hang',
                                       ps_killed_notify)
                Popen("notify-send \"{}\"".format(ps_killed_notify), shell=True)
                return
            else:
                try:
                    ps_killed_mssg = "Killed {} {} ({}) which was consuming {" \
                                     "} % memory (memory usage={})". \
                        format(i, ps.name(), ps.pid, ps.memory_percent(),
                               psutil.virtual_memory().percent)
                    ps.kill()
                    time.sleep(1)
                    ps_killed_mssg += "Current memory usage={}".\
                        format(psutil.virtual_memory().percent)
                    print(ps_killed_mssg)
                    ps_killed_notify += ps_killed_mssg + "\n"
                except Exception as err:
                    print("Error while killing {}: {}".format(ps.pid, err))
    else:
        print("Memory usage = " + str(psutil.virtual_memory().percent))
    root.update()


if __name__ == "__main__":
    while True:
        try:
            main()
        except Exception as err:
            print(err)
        time.sleep(1)

Guarde el código en un archivo, diga save_hang.py. Ejecute el script como:

sudo python save_hang.py

Tenga en cuenta que este script solo es compatible con Python 3 y requiere que instale el paquete tkinter. puedes instalarlo como:

sudo apt-get install python3-tk

Espero que esto ayude...

Saim Raza
fuente
2

Supongo que ha configurado su vm.swappinessvalor muy bajo, lo que hace que el kernel se intercambie demasiado tarde, dejando una RAM demasiado baja para que el sistema funcione.

Puede mostrar su configuración de intercambio actual ejecutando:

sysctl vm.swappiness

Por defecto, esto está configurado en 60. Ubuntu Wiki recomienda configurarlo en 10, pero no dude en configurarlo en un valor más alto. Puedes cambiarlo ejecutando:

sudo sysctl vm.swappiness=10

Esto lo cambiará solo para la sesión actual , para que sea persistente, debe agregarlo vm.swappiness = 10al /etc/sysctl.confarchivo.

Si su disco es lento, considere comprar uno nuevo.

Lekensteyn
fuente
En realidad, reducir el intercambio redujo el problema (sucedió más raramente). Lo estoy manteniendo a las 5 ahora. Aunque tal vez fue otro problema con el intercambio más alto, porque, cuando tenía 60 años, y decidí ver una película o editar un archivo grande, se cargó en la memoria todo el archivo og casi un GB y luego el sistema comenzó a intercambiar programas instantáneamente. utilizando activamente e incluso la propia interfaz de usuario. La cuestión es que creo que entiendo la parte de intercambio, lo que quiero es eliminar las aplicaciones de usuarios codiciosos en lugar de congelar la máquina cuando se está quedando sin RAM. (Y preferiblemente limite el tamaño del archivo en caché)
Krišjānis Nesenbergs
@Krisa: cuando el sistema se queda sin memoria (RAM e intercambio), el núcleo llama a oom_kill, que mata los procesos para ahorrar memoria. Lamentablemente, no puede controlar los procesos de destino. Para activarlo manualmente, presione Alt + SysRq + F. Al ejecutar el dmesgcomando, debería ver alguna información (y el nombre del proceso + id) del proceso. Creo que sería mejor comprar un disco nuevo y más rápido. O actualice su RAM.
Lekensteyn
3
El problema es que oom_kill simplemente no recibe una llamada antes de que la computadora se haya bloqueado durante unos 30 minutos. Además, ¿hay al menos una forma de saber qué proceso se eliminará primero?
Krišjānis Nesenbergs
2
Tengo 2 GB de RAM y el disco duro es de 5400 rpm. Realmente no creo que sea un sistema tan antiguo que justifica la congelación de media hora mientras mira un video en un monitor y navega unas 20-30 pestañas en el otro. En realidad, estaría muy feliz si siempre pudiera acceder a la consola y eliminar algunos procesos: ¿hay alguna manera de hacer que la entrada del usuario y el terminal tengan una prioridad súper alta para que funcione mientras el sistema se congela?
Krišjānis Nesenbergs
1
De todos modos, el intercambio y la cantidad de RAM es un poco fuera de tema. El problema es que el sistema deja de responder durante mucho tiempo, incluso si el intercambio está deshabilitado, y después de eso a veces aún ejecuta el programa (por lo que logra encontrar memoria en algún lugar) y otras veces ejecuta oom_killer. El sistema debería poder decir que se está quedando sin memoria RAM y simplemente no dejarme ejecutar más cosas. Entonces, ¿hay alguna forma de detener esas congelaciones o establecer una prioridad de entrada del usuario tan alta que pueda cambiar a la consola cuando sucedan y matar algunos procesos yo mismo?
Krišjānis Nesenbergs
2

He estado luchando con este problema durante mucho tiempo, pero ahora parece estar resuelto en mi computadora portátil.

Si ninguna de las otras respuestas funciona para usted (probé la mayoría de ellas), juegue con min_free_kbytes , para tener más espacio en la RAM cuando su computadora comience a intercambiar (justo antes de alcanzar este valor mínimo en su RAM libre).

Tengo 16 GB de RAM, pero más pronto que tarde la memoria se llenó y luego dejó de responder durante 10 a 30 minutos, hasta que algunas cosas se intercambiaron.

Al menos para mí, establecer el valor min_free_kbytes por encima de lo recomendado hace que el proceso de intercambio sea considerablemente más rápido.

Para 16 GB de RAM, intente esto:

vm.min_free_kbytes=500000

Para establecer este valor, vea otras respuestas, o simplemente búsquelo en Google :)

Beto Aveiga
fuente
0

Ejecuto una de mis computadoras portátiles desde una tarjeta SD de Ubuntu en vivo constantemente, con una pequeña partición de almacenamiento ext4 y un archivo de intercambio en el disco duro. Cuando se usa casi toda la RAM y el valor de intercambio es demasiado bajo (a veces prefiero mantener el disco duro completamente apagado si es posible, porque es ruidoso), el rendimiento de Linux tiende a caer por un precipicio para mí, de modo que simplemente llegar a TTY1 para matar a Firefox tarda 15 minutos.

El aumento /proc/sys/vm/vfs_cache_pressuredel valor predeterminado de 100 a un valor de 6000 parece ayudar a prevenir esto. Sin embargo, la documentación del núcleo advierte contra hacerlo, diciendo

Increasing vfs_cache_pressure significantly beyond 100 may have negative
performance impact. Reclaim code needs to take various locks to find freeable
directory and inode objects. With vfs_cache_pressure=1000, it will look for
ten times more freeable objects than there are.

No estoy completamente seguro de los efectos secundarios de hacer esto, así que tendría cuidado al hacerlo.

Hitechcomputergeek
fuente
Probablemente experimentará mejores resultados con vfs_cache_pressuremás cerca de 10 (es decir, mucho menos de 100) y una configuración min_free_kbytesmás alta. Tenga en cuenta que si establece min_free_kbytesdemasiado alto, ¡el asesino OOM de kernel matará a todos!
Mikko Rantalainen
@MikkoRantalainen Ya he subido min_free_kbytesa 262144, y he observado que bajar vfs_cache_pressuretiene el efecto contrario: bajarlo por debajo de 100 hace que el sistema deje de responder mucho más rápido. No estoy seguro de por qué exactamente.
Hitechcomputergeek
En general, el aumento vfs_cache_pressureprovocará que se arrojen directorios antes del contenido del archivo en caché y, como resultado, el rendimiento general generalmente se verá afectado con valores superiores a 100. Si puede encontrar los pasos para reproducir para bloquear / bloquear el sistema, por ejemplo, Ubuntu Live CD entonces los desarrolladores del kernel pueden descubrir la causa raíz. Para mí, el bloqueo se produce sin previo aviso. Mi mejor suposición es que el núcleo se bloquea debido a OOM antes de que OOM Killer haya liberado suficiente RAM. Ahora estoy ejecutando min_free_kbytes = 100000, admin_reserve_kbytes = 250000 y user_reserve_kbytes = 500000.
Mikko Rantalainen
(cont) Todavía no me he bloqueado con la configuración anterior a pesar de que tengo swappiness = 5 y vfs_cache_pressure = 20. El sistema tiene 16 GB de RAM y 8 GB de intercambio en SSD. Otro sistema tiene 32 GB de RAM y cero intercambio y al azar parece sufrir el mismo problema: presionar Alt + SysRq + f después de que el sistema se siente lento parece ayudar, así que supongo que si OOM Killer actuara lo suficientemente rápido, el sistema no se bloqueará.
Mikko Rantalainen