Cómo domar la capacidad de respuesta, la memoria y la paginación de Linux

27

Primera pregunta sobre desbordamiento =) ... +100 recompensa. No podía pensar en algo que realmente me importara hasta ahora:

Estoy realmente harto del estado de la capacidad de respuesta de escritorio de Linux, por ejemplo, http://brainstorm.ubuntu.com/item/85/ : en situaciones con poca RAM libre o situaciones con alto rendimiento de disco, el sistema se ralentiza un rastreo ; Esto es absolutamente terrible para aplicaciones que requieren un rendimiento decente. Además, la interfaz de usuario no responde por completo. Compare esto, por ejemplo, con OS X, donde si una aplicación está acaparando recursos, siempre se puede hacer clic en la opción para forzar el cierre, mientras que en Linux ni siquiera puedo presionar alt-tab o cambiar el escritorio, o incluso ctrl-alt-f1 para obtener un terminal: bueno, puedo, solo toma alrededor de 1-2 minutos por operación.

Uso gkrellm para poder ver la situación a medida que se desarrolla. Por lo general, la utilización de la memoria se vuelve bastante alta o el rendimiento del disco salta dramáticamente.

No es un mal hardware, con un quad-core de 2.6GHz y 4GB de RAM DDR2 de 800MHz (habría tenido 6GB, pero debido a una incompatibilidad de hardware no se podía mezclar y combinar con el conjunto anterior). Este problema puede desaparecer cuando inevitablemente obtenga más RAM, pero no creo que ese sea el corazón del problema. Incluso tengo dos particiones de intercambio en diferentes discos.

Siento que el problema es triple:

  • Programas fuera de control que acumulan grandes cantidades de memoria: la ley debe establecerse para estos programas, con límites en su
    • (por ejemplo, pestañas en Chrome, cada una de las cuales tiene entre 20 y 50 MB, algunas de las cuales pueden usar cientos de MB)
    • (por ejemplo, otros programas como update-db e indexadores que he tenido que deshabilitar y eliminar de cron porque estaban ralentizando el sistema cuando se ejecutaban, etc.)
  • algo terrible entra en la contienda del kernel o bus de algún tipo, de modo que las situaciones de alto rendimiento de disco ralentizan todo el sistema (tal vez al paginar programas importantes)
  • el kernel no prioriza la interfaz de usuario o los programas importantes en términos de recursos, como memoria, paginación e incluso la utilización del procesador

Los votos a favor van a:

Por lo tanto, estoy buscando una solución donde todos esos programas desaparezcan. En particular, estoy buscando una solución para que los procesos se ralenticen proporcionalmente, mientras que el sistema y otros programas no se ven afectados y responden lo suficiente como para matar algo manualmente. Además, el proceso del administrador de ventanas (y cualquier otra cosa que pueda afectar la capacidad de respuesta de la interfaz de usuario) debe responder en todas las circunstancias.

En particular, estoy intrigado por /etc/security/limits.conf( man limits.conf), pero me preocupa que esto solo dé control por usuario, y los ejemplos comentados en el archivo parecen bastante opacos en términos de descripción o dónde comenzar. Espero que limits.conffuncione, pero no me sorprendería si ni siquiera funcionara, o si no fuera una solución adecuada para mi problema, o tan granular como estoy tratando de lograrlo. Un nombre por proceso limits.confsería ideal, suponiendo nuevamente que limit.conf funciona. Estaría encantado de probar un límite. Conf. Que la gente proporciona, para probar si funciona, aunque estoy abierto a todas las soluciones en este momento.

También podría ser útil tener alguna idea de cómo OS X logra mantener una respuesta de interfaz de usuario tan buena.

Ya modifiqué mis /tmpcarpetas y la caché para que estén activadas tmpfs, y en general la utilización del disco es casi nula.

Temas vagamente relacionados:

  • exceso de memoria

Respuestas que no creo que funcionen:

  • swapoff (Esto todavía permite que los programas de memoria de memoria se salgan con la suya, y el sistema se congele permanentemente si la memoria es realmente mala - vota a cualquiera que pueda sugerir un ajuste que invocó al asesino de OOM antes de intercambiar y apunte a programas específicos)
  • echo ?? > /sys/.../swappiness (sin efecto discernible)
  • nice (nunca ha funcionado)
  • ionice (nunca noté una diferencia)
  • selinux (la incompatibilidad del programa parece ser una pesadilla)
  • Linux en tiempo real, es decir, puede interrumpir el kernel (no quiere lidiar con la compilación y actualización del kernel personalizado; podría estar bien si se ha migrado a los repositorios)
  • * *
usuario76871
fuente
hmm, parece que no puedo hacer una recompensa; ? Creo que el enlace no se presentó a 48 h ... bueno voy a publicar la generosidad con toda la reputación que he adquirido a continuación
user76871
1
+1, este es el mayor problema que tengo con el escritorio de Linux en el día a día. Tengo congelaciones ocasionales, tal vez una vez cada dos semanas, pero no son suficientes para ser particularmente molestas. Sin embargo, solo parece ser un problema con las aplicaciones que tienen, como dijiste, una gran utilización de E / S : las aplicaciones que tienen una gran utilización de la CPU no tienen ningún efecto en el rendimiento general del sistema. No sabía sobre ionice, parece que sería la solución correcta a este problema si funcionara correctamente.
crazy2be
1
3 años después y esto sigue siendo un problema en Linux. @ crazy2be o user76871, no creo que haya encontrado una solución mientras tanto.
Glutanimate
@Glutanimate: sí, 32 GB de RAM física y nada menos (bueno, tal vez 16 GB ... pero eso es lo que lo empuja), también pueden ser grandes cantidades de RAM de video. Esto no soluciona la falta de respuesta debido a la alta CPU o las interrupciones o cualquier otra cosa, pero evita la falta de respuesta en situaciones de poca memoria.
user76871

Respuestas:

6

Parece que su sistema entra en un intercambio pesado. El uso vmstat 1puede revelar algunos detalles: simplemente déjelo correr en una ventana de terminal y cambie a él cuando comience la desaceleración.

En lugar de poner / tmp y "caché" en tmpfs, usaría un sistema de archivos de disco normal montado con la noatimeopción. A menudo, los datos utilizados permanecerán en los cachés de todos modos, y los datos más antiguos se pueden escribir en el disco para liberar algo de RAM para las aplicaciones. Si / tmp y / o el caché crecen, esto podría ayudar mucho.

Turbo J
fuente
1
+1 por mencionar noatime.
LawrenceC
Gracias por mencionar noatime, desafortunadamente solía usar esa opción de montaje, y no creo que haya ayudado mucho para garantizar la capacidad de respuesta (aunque ayuda muchísimo para garantizar que el disco no esté sobrecargado); solo para asegurarme de que he vuelto a habilitar noatime en mi configuración actual. Sin embargo, tener un no tmpfs con noatime parece un poco extraño, ya que todavía imagino que deben ocurrir escrituras masivas.
user76871
+1, probado vmstat 1: extremadamente útil para confirmar el diagnóstico de que el intercambio es, de hecho, una gran parte del problema principal
usuario76871
2
Ay. Nunca vi un sistema Linux que necesitara un intercambio tan pesado. ¿Ha verificado con df -mcuánta memoria se usa en los sistemas de archivos tmpfs? Algo está comiendo tu RAM relativamente rápido.
Turbo J
Gracias por la sugerencia y por enseñarme sobre la -mopción. Desafortunadamente, df -h -mparece indicar que solo hay 100 MB de mi memoria tmpfs, así que dudo que esté relacionado con el uso de memoria para tmpfs y cachés. Esto tampoco parece tan raro; He tenido que suceder en múltiples distribuciones cuando su RAM se empuja cerca del límite.
user76871
5

No soy desarrollador de kernel, pero pasé años filosofando sobre este tema porque me encontré con esto muchas veces. De hecho, se me ocurrió una metáfora de toda la situación, así que déjame decirte eso. Asumiré en mi historia que cosas como "swap" no existen. El intercambio no tiene mucho sentido con 32 GB de RAM en estos días de todos modos.

Imagine un vecindario suyo donde el agua está conectada a cada edificio a través de tuberías y las ciudades necesitan administrar la capacidad. Supongamos que solo tiene una producción de 100 unidades de agua por segundo (y toda la capacidad no utilizada se desperdicia porque no tiene tanques de reserva). Cada hogar (hogar = una pequeña aplicación, una terminal, el widget de reloj, etc.) requiere una unidad de agua por segundo. Todo esto es bueno y bueno porque su población es de 90, por lo que todos obtienen suficiente agua.

Ahora el alcalde (= usted) decide que desea abrir un gran restaurante (= navegador). Este restaurante albergará múltiples cocineros (= pestañas del navegador). Cada cocinero necesita 1 unidad de agua por segundo. Comienzas con 10 cocineros, por lo que el consumo total de agua para todo el vecindario es de 100 unidades de agua, lo que sigue siendo bueno.

Ahora comienzan las cosas divertidas: contratas a otro cocinero en tu restaurante, lo que hace que los requisitos totales de agua sean 101, lo que obviamente no tienes. Necesitas hacer algo.

La gestión del agua (= kernel) tiene 3 opciones.

1. La primera opción es simplemente desconectar el servicio para las casas que no usaron el agua recientemente. Esto está bien, pero si la casa desconectada quiere volver a usar el agua, tendrá que pasar por el largo proceso de registro nuevamente. La administración puede desconectar varias viviendas para liberar más recursos hídricos. En realidad, desconectarán todas las casas que no usaron agua recientemente, manteniendo así una cierta cantidad de agua gratuita siempre disponible.

Aunque su ciudad sigue funcionando, la desventaja es que el progreso se detiene. La mayor parte de su tiempo se dedica a esperar a que la administración del agua restablezca su servicio.

Esto es lo que hace el núcleo con las páginas respaldadas por archivos. Si ejecuta un archivo ejecutable grande (como Chrome), su archivo se copia en la memoria. Cuando hay poca memoria o si hay partes a las que no se ha accedido recientemente, el kernel puede descartar esas partes porque de todos modos puede volver a cargarlas desde el disco. Si esto se hace en exceso, esto detiene su escritorio porque todo estará esperando el disco IO. Tenga en cuenta que el kernel también soltará muchas páginas menos utilizadas recientemente cuando comience a hacer muchas IO. Es por eso que lleva años cambiar a una aplicación en segundo plano después de copiar varios archivos grandes, como imágenes de DVD.

Este es el comportamiento más molesto para mí porque odio los hickups y no tienes ningún control sobre eso. Sería bueno poder apagarlo. Estoy pensando en algo en la línea de

sed -i 's/may_unmap = 1/may_unmap = (vm_swappiness >= 0)/' mm/vmscan.c

y luego puede establecer vm_swappiness en -1 para deshabilitar esto. Esto funcionó bastante bien en mis pequeñas pruebas, pero lamentablemente no soy un desarrollador de kernel, así que no se lo envié a nadie (y obviamente la pequeña modificación anterior no está completa).

2)La gerencia podría negar la solicitud de agua del nuevo cocinero. Esto inicialmente suena como una buena idea. Sin embargo, hay dos desventajas. Primero, hay compañías que solicitan muchas suscripciones de agua a pesar de que no las usan. Una posible razón para hacer esto es evitar toda la sobrecarga de hablar con la administración del agua siempre que necesiten un poco de agua adicional. Su consumo de agua aumenta y disminuye según la hora del día. Por ejemplo, en el caso del restaurante, la compañía necesita mucha más agua durante el mediodía en comparación con la medianoche. Entonces, solicitan toda el agua posible que puedan usar, pero eso desperdicia las asignaciones de agua durante la medianoche. El problema es que no todas las compañías pueden prever su uso máximo correctamente, por lo que solicitan mucho más con la esperanza de que nunca tengan que preocuparse por solicitar más.

Esto es lo que hace la máquina virtual de Java: asigna un montón de memoria al inicio y luego funciona a partir de eso. Por defecto, el núcleo solo asignará la memoria cuando su aplicación Java realmente comience a usarla. Sin embargo, si deshabilita el exceso de confirmación, el núcleo tomará en serio la reserva. Solo permitirá que la asignación tenga éxito si realmente tiene los recursos para ello.

Sin embargo, hay otro problema más grave con este enfoque. Digamos que una empresa comienza a solicitar una sola unidad de agua todos los días (en lugar de hacerlo en pasos de 10). Eventualmente alcanzarás un estado donde tienes 0 unidades libres. Ahora esta compañía no podrá asignar más. De todos modos, a quién le importan las grandes empresas. ¡Pero el problema es que las casas pequeñas tampoco podrán solicitar más agua! No podrá construir pequeños baños públicos para hacer frente a la afluencia repentina de turistas. No podrá proporcionar agua de emergencia para el incendio en el bosque cercano.

En términos de computadora: en situaciones de poca memoria sin exceso de compromiso, no podrá abrir un nuevo xterm, no podrá ingresar a su máquina, no podrá abrir una nueva pestaña para buscar posibles arreglos En otras palabras, deshabilitar el exceso de compromiso también hace que su escritorio sea inútil cuando tiene poca memoria.

3. Ahora aquí hay una forma interesante de manejar el problema cuando una empresa comienza a usar demasiada agua. ¡La gestión del agua lo explota! Literalmente: va al sitio del restaurante, arroja dinamitas y espera hasta que explota. Esto reducirá instantáneamente los requisitos de agua de la ciudad en gran medida para que las personas nuevas puedan mudarse, pueda crear baños públicos, etc. Usted, como alcalde, puede reconstruir el restaurante con la esperanza de que esta vez requiera menos agua. Por ejemplo, le dirá a la gente que no vaya a los restaurantes si ya hay demasiada gente adentro (por ejemplo, abrirá menos pestañas del navegador).

Esto es realmente lo que hace el núcleo cuando se queda sin todas las opciones y necesita memoria: llama al asesino OOM. Elige una aplicación grande (basada en muchas heurísticas) y la mata, liberando un montón de memoria pero manteniendo un escritorio receptivo. En realidad, el kernel de Android hace esto aún más agresivamente: mata la aplicación utilizada menos recientemente cuando la memoria es baja (en comparación con el kernel de inventario que lo hace solo como último recurso). Esto se llama Viking Killer en Android.

Creo que esta es una de las soluciones más simples para el problema: no es que tenga más opciones que esta, así que ¿por qué no superarlo más pronto que tarde, verdad? El problema es que el kernel a veces hace mucho trabajo para evitar invocar al asesino OOM. Es por eso que ves que tu escritorio es muy lento y el kernel no está haciendo nada al respecto. ¡Pero afortunadamente hay una opción para invocar al asesino OOM usted mismo! Primero, asegúrese de que la clave mágica sysrq esté habilitada (por ejemplo echo 1 | sudo tee /proc/sys/kernel/sysrq), luego, cuando sienta que el núcleo se está quedando sin memoria, simplemente presione Alt + SysRQ, Alt + f.

Bien, ¿todo eso es bueno pero quieres probarlo? La situación de poca memoria es muy simple de reproducir. Tengo una aplicación muy simple para eso. Deberá ejecutarlo dos veces. La primera ejecución determinará la cantidad de RAM libre que tiene, la segunda ejecución creará la situación de poca memoria. Tenga en cuenta que este método supone que tiene el intercambio deshabilitado (por ejemplo, hacer a sudo swapoff -a). Código y uso a continuación:

// gcc -std=c99 -Wall -Wextra -Werror -g -o eatmem eatmem.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char** argv)
{
    int limit = 123456789;
    if (argc >= 2) {
        limit = atoi(argv[1]);
    }
    setbuf(stdout, NULL);
    for (int i = 1; i <= limit; i++) {
        memset(malloc(1 << 20), 1, 1 << 20);
        printf("\rAllocated %5d MiB.", i);
    }
    sleep(10000);
    return 0;
}

Y así es como lo usas:

$ gcc -std=c99 -Wall -Wextra -Werror -g -o eatmem eatmem.c
$ ./eatmem
Allocated 31118 MiB.Killed
$ ./eatmem 31110
Allocated 31110 MiB.Killed

La primera invocación detectó que tenemos 31,118 MiB de RAM libre. Entonces le dije a la aplicación que asignara 31,110 MiB RAM para que el kernel no lo matara, sino que consumiera casi toda mi memoria. Mi sistema se congeló: incluso el puntero del mouse no se movió. Presioné Alt + SysRQ, Alt + f y mató mi proceso eatmem y el sistema se restauró.

Aunque cubrimos nuestras opciones sobre qué hacer en una situación de poca memoria, el mejor enfoque (como cualquier otra situación peligrosa) es evitarlo en primer lugar. Hay muchas maneras de hacer esto. Una forma común que he visto es colocar las aplicaciones que se comportan mal (como los navegadores) en diferentes contenedores que el resto del sistema. En ese caso, el navegador no podrá afectar su escritorio. Pero la prevención en sí está fuera del alcance de la pregunta, por lo que no escribiré al respecto.

TL; DR: aunque actualmente no hay forma de evitar completamente la paginación, puede mitigar la detención total del sistema deshabilitando el exceso de compromiso. Pero su sistema seguirá siendo inutilizable durante una situación de poca memoria, pero de una manera diferente. Independientemente de lo anterior, en una situación de poca memoria, presione Alt + SysRQ, Alt + f para eliminar un gran proceso de elección del núcleo. Su sistema debería restaurar su capacidad de respuesta después de unos segundos. Esto supone que tiene habilitada la clave mágica sysrq (no está predeterminada).

ypsu
fuente
Le di toda mi reputación como recompensa por este recurso, por lo que ni siquiera podía dejar un comentario :) Finalmente, gané un poco para agradecerle por esta gran respuesta. Estaba lidiando con este problema todo el tiempo que tenía mi laptop con 8GB (loco, pero mi sistema se estaba quedando sin memoria regularmente esos días). Recientemente, encontré este proyecto: github.com/rfjakob/earlyoom , que podría ayudar a evitar que el sistema se bloquee al matar algunos procesos antes de que sea demasiado tarde.
Vlad Frolov
4

Poner todos sus archivos temporales y de caché en una tmpfsestá reduciendo la cantidad de RAM libre que tiene, por lo que podría estar causando que el sistema se intercambie antes de lo necesario sin esto.

Parece que tiene algunas aplicaciones que dependen de algún tipo de instalación de kernel o controlador que se está sobrecargando. No entra en demasiados detalles sobre qué tipos de aplicaciones, además de los navegadores e indexadores, está utilizando, y que ha deshabilitado los indexadores.

Puede intentar cambiar a un entorno de escritorio o administrador de ventanas que consuma menos recursos, como LXDE o IceWM. En el trabajo, uso un sistema Linux con LXDE instalado y ROX-Filer para un entorno de escritorio muy mínimo. El propósito de este sistema Linux es ejecutar VMWare Player para que pueda ejecutar Windows XP y Windows 7 simultáneamente. Son especificaciones de hardware similares a las que usted dice y no tengo demasiados problemas de capacidad de respuesta bajo esta carga pesada por la que estoy pasando el hardware. No tengo ningún problema de respuesta con Linux en sí mismo (generalmente son las máquinas virtuales las que a veces me hacen esperar un segundo, y compartir este disco entre 2 máquinas virtuales + 1 sistema operativo es lo que se espera) y siempre he podido suspender o apagar las máquinas virtuales siempre que sea necesario. Quiero.

Entonces, para mí, señala un problema con las aplicaciones específicas que está ejecutando.

¿DMA está habilitado para sus unidades de disco? (uso hdparm) Si está utilizando el cifrado de disco completo, eso requiere que todo el tráfico del disco pase a través de la CPU, lo que niega gran parte del beneficio de DMA. El efecto de eso sería que el alto tráfico de disco hace que la CPU se dispare, lo que luego ralentizaría todo el sistema. (EDITAR: para aclarar, tener DMA deshabilitado O usar dm-cryptcausará CPU alta durante el tráfico de disco alto)

LawrenceC
fuente
2
El punto de la pregunta no es que el WM esté hinchado y que el sistema se vuelva lento (es probable que responda perfectamente bajo el uso normal), sino que el núcleo no prioriza adecuadamente las aplicaciones cuando se queda sin memoria y tiene que entrar intercambio pesado. He tenido este problema en todos los Linux de escritorio que he usado, y aunque usar programas más livianos o agregar más ram podría ayudar, no resuelve la raíz del problema.
crazy2be
En mi publicación anterior dije lo siguiente: "Parece que tienes algunas aplicaciones que dependen de algún tipo de instalación de kernel o controlador que se está sobrecargando". Quizás el cuello de botella esté en un módulo de kernel específico. No soy un experto en kernel, pero estoy seguro de que la asignación de memoria desde el lado del kernel, especialmente del lado del módulo, funciona de manera diferente al lado del usuario. La utilización de la CPU en el lado del kernel también se maneja de manera diferente (no sé si puede "hacer buenos" los procesos del kernel). No puedo comentar más sin conocer las aplicaciones específicas involucradas.
LawrenceC
Además, si está utilizando FUSE NTFS que puede causar lentitud.
LawrenceC
1
Soy consciente de que un sistema de archivos basado en RAM como tmpfs (obviamente) hace que la RAM se agote más rápido, y que un WM ligero puede reducir ligeramente los síntomas del problema subyacente. Me sentí presionada a usar tmpfs debido a la poca capacidad de respuesta que puede causar la escritura en el disco. Sin embargo, gracias por su sugerencia, especialmente la parte sobre DMA, que he agregado a la lista de temas posiblemente relacionados. Para el registro, creo que DMA está habilitado, y no estoy usando un sistema de archivos criptográfico.
user76871
1

Este es un problema común con el planificador de Linux. El sistema se ralentiza cada vez que ocurren actividades pesadas IO. Realmente no hay muchas cosas que podría hacer para mejorar la situación a menos que esté interesado en la piratería de kernel :)

Quizás estos puedan ayudar:

http://www.phoronix.com/scan.php?page=article&item=linux_2637_video&num=1

http://www.osnews.com/story/24223/Alternative_to_the_200_Lines_Kernel_Patch_that_Does_Wonders_

Lamnk
fuente
1
Como recuerdo, esos parches de kernel realmente solo son relevantes si está compilando un programa o haciendo algo más que es muy CPU (y IO?) En un terminal , mientras intenta interactuar con aplicaciones GUI. Desafortunadamente, no ayuda en la situación más común en la que una aplicación GUI está haciendo un trabajo pesado y está intentando trabajar con otra aplicación GUI.
crazy2be
0

Aunque la pregunta tiene más de dos años y la respuesta de @ ypsu es excelente, la situación con los sistemas basados ​​en Linux que van mal debido a la falta de RAM todavía está aquí.

Aquí está mi observación sobre el problema: incluso si no tengo ningún intercambio, una vez que el sistema tiene poca memoria, el indicador de mi disco duro se ilumina ya que es 100% de carga de disco. Dado este hecho, parece que la causa raíz es que el kernel intenta liberar memoria descargando algo que se puede restaurar del disco, y es, sin duda, las bibliotecas compartidas. Dado que las aplicaciones GUI generalmente tienen toneladas de bibliotecas compartidas, parece que el sistema puede pensar que es suficiente descargar solo algunas de ellas, pero eso solo funciona hasta la próxima operación de espacio de usuario que requiere esas bibliotecas descargadas. Este parece ser el escenario más probable que causa el ciclo sin fin de descargar bibliotecas compartidas y volver a cargarlas.

Hay un proyecto que actúa como un demonio de espacio de usuario que mata los procesos que más memoria requieren antes de que sea demasiado tarde: https://github.com/rfjakob/earlyoom

Además, solía usar contenedores Docker con límites de memoria razonables para las aplicaciones con mucha memoria (por ejemplo, Chrome).

Vlad Frolov
fuente