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 MemAvailable
campo. 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 Shmem
memoria no se pueden liberar, solo se mueven para intercambiar. Cached
in /proc/meminfo
puede ser muy engañoso, debido a la inclusión de esta Shmem
memoria intercambiable . Si tiene demasiados archivos en un archivo tmpfs, podría estar ocupando mucha memoria :-). Shmem
También puede incluir algunas asignaciones de memoria gráfica , que podrían ser muy grandes.
MemAvailable
deliberadamente 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 MemAvailable
funciona. 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 Shmem
como memoria "usada". Creé varios archivos de 1GB en un tmpfs. Cada aumento de 1 GB se Shmem
reduce MemAvailable
en 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 MemAvailable
cá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 firefox
con 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 MemAvailable
está 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
, cgroups
y 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_beancounters
muestra el uso actual y los límites. vzubc
lo 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_rss
como 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.stat
archivo. Todos los campos se suman sobre cgroups secundarios, por lo que no necesita buscar total_...
campos. Hay un file
campo, lo que significa que lo mismo cache
hizo. Molesto, no veo un campo general como el rss
interior 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/meminfo
con un archivo falsificado por el software contenedor específico . La utilidad de los valores falsos dependerá de lo que haga ese software específico.
systemd
cree que cgroup-v1 no se puede delegar de forma segura, por ejemplo, a contenedores. Miré dentro de un systemd-nspawn
contenedor 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 systemd
no 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).
MemAvailable
, se agregó en 3.14.