¿Es la memoria "en caché" de facto libre?

11

Cuando se ejecuta cat /proc/meminfo, obtiene estos 3 valores en la parte superior:

MemTotal:        6291456 kB
MemFree:         4038976 kB
Cached:          1477948 kB

Hasta donde yo sé, el valor "en caché" es el almacenamiento en caché de disco realizado por el sistema Linux que se liberará de inmediato si alguna aplicación necesita más RAM, por lo tanto, Linux nunca se quedará sin memoria hasta que MemFree y Cached estén en cero.

Desafortunadamente, / proc / meminfo no informa "MemAvailable", probablemente porque se está ejecutando en un servidor virtual. (La versión del kernel es 4.4)

Por lo tanto, a todos los efectos prácticos, la RAM disponible para las aplicaciones es MemFree + Cached.

¿Es correcta esa opinión?

Roland Seuhs
fuente
1
No quiero que el oro este cerrado, pero esta pregunta es relevante si no es un duplicado. Me sorprende que no tenga MemAvailable, se agregó en 3.14.
Stephen Kitt
La respuesta aceptada de esa pregunta usa / proc / zoneinfo, que tampoco está disponible en mi servidor virtual
Roland Seuhs, del
uname -a: host Linux 4.4.0-042stab134.8 # 1 SMP vie 7 de diciembre 17:16:09 MSK 2018 x86_64 x86_64 x86_64 GNU / Linux
Roland Seuhs
Sospecho que este es un sistema OpenVZ con un núcleo que realmente se basa en 2.6.32, no 4.4.
Stephen Kitt,
1
@sourcejedi y se compiló exactamente al mismo tiempo que el kernel 4.4.
Stephen Kitt

Respuestas:

10

Esa visión puede ser muy engañosa en varios casos del mundo real.

El núcleo ahora proporciona una estimación de la memoria disponible, en el MemAvailablecampo. Este valor es significativamente diferente de MemFree + Cached.

/ proc / meminfo: proporciona memoria disponible estimada [descripción del cambio de kernel, 2014]

Muchos programas de equilibrio de carga y colocación de carga de trabajo verifican / proc / meminfo para estimar la cantidad de memoria disponible. Por lo general, hacen esto agregando "gratis" y "en caché", lo que estaba bien hace diez años, pero está casi garantizado que hoy está mal.

Está mal porque la memoria caché incluye memoria que no se puede liberar como memoria caché de página, por ejemplo, segmentos de memoria compartida, tmpfs y ramfs, y no incluye memoria de losa recuperable, que puede ocupar una gran fracción de la memoria del sistema en la mayoría de los sistemas inactivos con muchos archivos

Actualmente, la cantidad de memoria disponible para una nueva carga de trabajo, sin empujar el sistema a cambio, se puede estimar a partir de MemFree, Active (archivo), Inactive (archivo) y SReclaimable, así como las marcas de agua "bajas" de / proc / zoneinfo. Sin embargo, esto puede cambiar en el futuro, y no se debe esperar que el espacio del usuario conozca los componentes internos del kernel para obtener una estimación de la cantidad de memoria libre. Es más conveniente proporcionar dicha estimación en / proc / meminfo. Si las cosas cambian en el futuro, solo tenemos que cambiarlo en un solo lugar.
...

Documentation / filesystems / proc.txt:
...
MemAvailable: una estimación de la cantidad de memoria disponible para iniciar nuevas aplicaciones, sin intercambio. Calculado a partir de MemFree, SReclaimable, el tamaño de las listas de archivos LRU y las marcas de agua bajas en cada zona. La estimación tiene en cuenta que el sistema necesita un poco de caché de página para funcionar bien, y que no todas las losas recuperables serán recuperables, debido a que los artículos están en uso. El impacto de esos factores variará de un sistema a otro.

1. Detalles de MemAvailable

Como dice anteriormente, tmpfs y otra Shmemmemoria no se pueden liberar, solo se mueven para intercambiar. Cachedin /proc/meminfopuede ser muy engañoso, debido a la inclusión de esta Shmemmemoria intercambiable . Si tiene demasiados archivos en un archivo tmpfs, podría estar ocupando mucha memoria :-). ShmemTambién puede incluir algunas asignaciones de memoria gráfica , que podrían ser muy grandes.

MemAvailabledeliberadamente no incluye memoria intercambiable. Intercambiar demasiado puede causar largas demoras. Incluso podría haber elegido ejecutar sin espacio de intercambio, o permitir solo una cantidad relativamente limitada.

Tuve que verificar dos veces cómo MemAvailablefunciona. A primera vista, el código no parecía mencionar esta distinción.

/*
 * Not all the page cache can be freed, otherwise the system will
 * start swapping. Assume at least half of the page cache, or the
 * low watermark worth of cache, needs to stay.
 */
pagecache = pages[LRU_ACTIVE_FILE] + pages[LRU_INACTIVE_FILE];
pagecache -= min(pagecache / 2, wmark_low);
available += pagecache;

Sin embargo, descubrí que trata correctamente Shmemcomo memoria "usada". Creé varios archivos de 1GB en un tmpfs. Cada aumento de 1 GB se Shmemreduce MemAvailableen 1 GB. Por lo tanto, el tamaño de las "listas de archivos LRU" no incluye la memoria compartida ni ninguna otra memoria intercambiable. (Noté que estos mismos recuentos de páginas también se usan en el código que calcula el "límite sucio" ).

Este MemAvailablecálculo también supone que desea mantener al menos suficiente caché de archivos para igualar la "marca de agua baja" del núcleo. O la mitad del caché actual, el que sea más pequeño. (También hace la misma suposición para las losas recuperables). La "marca de agua baja" del núcleo se puede ajustar, pero generalmente es alrededor del 2% de la RAM del sistema . Entonces, si solo desea una estimación aproximada, puede ignorar esta parte :-).

Cuando está ejecutando firefoxcon alrededor de 100 MB de código de programa asignado en la memoria caché de la página, generalmente desea mantener esos 100 MB en RAM :-). De lo contrario, en el mejor de los casos sufrirá retrasos, en el peor de los casos, el sistema pasará todo su tiempo revolviendo entre diferentes aplicaciones. Entonces MemAvailableestá permitiendo un pequeño porcentaje de RAM para esto. Puede que no permita lo suficiente, o puede ser demasiado generoso. "El impacto de esos factores variará de un sistema a otro".

Para muchas cargas de trabajo de PC, el punto sobre "muchos archivos" podría no ser relevante. Aun así, actualmente tengo 500 MB de memoria de losa recuperable en mi computadora portátil (de 8 GB de RAM). Esto se debe a ext4_inode_cache(más de 300K objetos). Sucedió porque recientemente tuve que escanear todo el sistema de archivos, para encontrar lo que estaba usando mi espacio en disco :-). Usé el comando df -x / | sort -n, pero, por ejemplo, Gnome Disk Usage Analyzer haría lo mismo.

2. [editar] Memoria en grupos de control

Los llamados "contenedores" de Linux se construyen a partir namespaces, cgroupsy varias otras características según el gusto :-). Pueden proporcionar un entorno lo suficientemente convincente como para ejecutar algo parecido a un sistema Linux completo. Los servicios de alojamiento pueden construir contenedores como este y venderlos como "servidores virtuales" :-).

Los servidores de alojamiento también pueden construir "servidores virtuales" utilizando características que no están en Linux principal. Los contenedores OpenVZ son anteriores a los cgroups de la línea principal por dos años y pueden usar "contadores de frijoles" para limitar la memoria. Por lo tanto, no puede comprender exactamente cómo funcionan esos límites de memoria si solo lee documentos o hace preguntas sobre el núcleo principal de Linux. cat /proc/user_beancountersmuestra el uso actual y los límites. vzubclo presenta en un formato un poco más amigable. La página principal en beancounters documenta los nombres de las filas.

Los grupos de control incluyen la capacidad de establecer límites de memoria en los procesos dentro de ellos. Si ejecuta su aplicación dentro de dicho cgroup, entonces no toda la memoria del sistema estará disponible para la aplicación :-). Entonces, ¿cómo podemos ver la memoria disponible en este caso?

La interfaz para esto difiere de varias maneras, dependiendo de si usa cgroup-v1 o cgroup-v2 .

La instalación de mi computadora portátil usa cgroup-v1. Puedo correr cat /sys/fs/cgroup/memory/memory.stat. El archivo muestra varios campos, incluyendo total_rss, total_cache, total_shmem. shmem, incluido tmpfs, cuenta para los límites de memoria. Supongo que puedes verlo total_rsscomo un equivalente inverso de MemFree. Y también está el archivo memory.kmem.usage_in_bytes, que representa la memoria del núcleo, incluidas las losas. (Supongo que memory.kmem.también incluye memory.kmem.tcp.y cualquier extensión futura, aunque esto no está documentado explícitamente). No hay contadores separados para ver la memoria de losa recuperable. El documento para cgroup-v1 dice golpear los límites de memoria no no desencadenar recuperación de cualquier memoria losa. (El documento también tiene un descargo de responsabilidad de que está "irremediablemente desactualizado", y que debe verificar el código fuente actual).

cgroup-v2 es diferente. Creo que el cgroup raíz (nivel superior) no admite la contabilidad de memoria. cgroup-v2 todavía tiene un memory.statarchivo. Todos los campos se suman sobre cgroups secundarios, por lo que no necesita buscar total_...campos. Hay un filecampo, lo que significa que lo mismo cachehizo. Molesto, no veo un campo general como el rssinterior memory.stat; Supongo que tendrías que sumar campos individuales. Hay estadísticas separadas para la memoria de losa recuperable y no recuperable; Creo que un v2 cgroup está diseñado para reclamar losas cuando comienza a quedarse sin memoria.

Los cgroups de Linux no se virtualizan automáticamente /proc/meminfo(o cualquier otro archivo /proc), por lo que eso mostraría los valores para toda la máquina. Esto confundiría a los clientes de VPS. Sin embargo, es posible usar espacios de nombres para reemplazar /proc/meminfocon un archivo falsificado por el software contenedor específico . La utilidad de los valores falsos dependerá de lo que haga ese software específico.

systemdcree que cgroup-v1 no se puede delegar de forma segura, por ejemplo, a contenedores. Miré dentro de un systemd-nspawncontenedor en mi sistema cgroup-v1. Puedo ver el cgroup en el que se ha colocado dentro, y la memoria que explica eso. Por otro lado, el contenido systemdno configura los cgroups habituales por servicio para la contabilidad de recursos. Si la contabilidad de memoria no estaba habilitada dentro de este cgroup, supongo que el contenedor no podría habilitarla.

Supongo que si está dentro de un contenedor cgroup-v2, se verá diferente a la raíz de un sistema cgroup-v2 real, y podrá ver la contabilidad de su cgroup de nivel superior. O si el cgroup que puede ver no tiene habilitada la contabilidad de memoria, es de esperar que se le delegue el permiso para que pueda habilitar la contabilidad de memoria ensystemd (o equivalente).

sourcejedi
fuente
1
es clicky nao. Uso enlaces de GitHub porque muestran la primera versión que contiene el commit (similar a git describe --contains). Lo encontré vinculado como un TL; DR por una pregunta SU, que resultó ser simplemente citando la sección agregada a proc.txt. Pero para esta pregunta, la descripción de confirmación es simplemente IMO perfecta :-).
sourcejedi
MemAvailable no parece estar disponible en la mayoría de los servidores virtuales ... ¿qué hacer entonces?
Roland Seuhs
@RolandSeuhs posiblemente aprenda "beanscounters". Ver ediciones en negrita. Si tiene alguna pregunta sobre los contadores de frijoles, le agradecería que haga una nueva pregunta. Siempre podemos vincularlo desde este, pero los detalles probablemente no sean relevantes para ningún lector que use un núcleo Linux de línea principal.
sourcejedi