¿Qué usó la memoria de Linux? Caché bajo, búfer bajo, no una VM

11

En primer lugar, sí, he leído LinuxAteMyRAM , que no explica mi situación.

# free -tm
             total       used       free     shared    buffers     cached
Mem:         48149      43948       4200          0          4         75
-/+ buffers/cache:      43868       4280
Swap:        38287          0      38287
Total:       86436      43948      42488
#

Como se muestra arriba, la -/+ buffers/cache:línea que se muestra indica que la velocidad de memoria utilizada es muy alta. Sin embargo, de la salida de top, no veo ningún proceso que use más de 100 MB de memoria.

Entonces, ¿qué usó la memoria?

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
28078 root      18   0  327m  92m  10m S    0  0.2   0:25.06 java
31416 root      16   0  250m  28m  20m S    0  0.1  25:54.59 ResourceMonitor
21598 root     -98   0 26552  25m 8316 S    0  0.1  80:49.54 had
24580 root      16   0 24152  10m  760 S    0  0.0   1:25.87 rsyncd
 4956 root      16   0 62588  10m 3132 S    0  0.0  12:36.54 vxconfigd
26703 root      16   0  139m 7120 2900 S    1  0.0   4359:39 hrmonitor
21873 root      15   0 18764 4684 2152 S    0  0.0  30:07.56 MountAgent
21883 root      15   0 13736 4280 2172 S    0  0.0  25:25.09 SybaseAgent
21878 root      15   0 18548 4172 2000 S    0  0.0  52:33.46 NICAgent
21887 root      15   0 12660 4056 2168 S    0  0.0  25:07.80 SybaseBkAgent
17798 root      25   0 10652 4048 1160 S    0  0.0   0:00.04 vxconfigbackupd

Esta es una máquina x86_64 (no un servidor de marca común) que ejecuta x84_64 Linux, no un contenedor en una máquina virtual. Kernel ( uname -a):

Linux 2.6.16.60-0.99.1-smp #1 SMP Fri Oct 12 14:24:23 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux

Contenido de /proc/meminfo:

MemTotal:     49304856 kB
MemFree:       4066708 kB
Buffers:         35688 kB
Cached:         132588 kB
SwapCached:          0 kB
Active:       26536644 kB
Inactive:     17296272 kB
HighTotal:           0 kB
HighFree:            0 kB
LowTotal:     49304856 kB
LowFree:       4066708 kB
SwapTotal:    39206624 kB
SwapFree:     39206528 kB
Dirty:             200 kB
Writeback:           0 kB
AnonPages:      249592 kB
Mapped:          52712 kB
Slab:          1049464 kB
CommitLimit:  63859052 kB
Committed_AS:   659384 kB
PageTables:       3412 kB
VmallocTotal: 34359738367 kB
VmallocUsed:    478420 kB
VmallocChunk: 34359259695 kB
HugePages_Total:     0
HugePages_Free:      0
HugePages_Rsvd:      0
Hugepagesize:     2048 kB

dfinforma que no hay gran consumo de memoria de los tmpfssistemas de archivos.

Jason
fuente
2
¿Cuál es el resultado de ps -eo pid,user,args,pmem --sort pmem?
Braiam
Pegué aquí el enlace , lo intenté algunas veces, obtuve el mismo resultado.
Jason
3
No lo use head! Quiero la salida completa del comando completo. Si quisiera que headlo usaras, lo pondría a mi disposición. Por favor, siempre proporcione el resultado completo al comando que la gente pregunta.
Braiam
3
En un teléfono, no recuerdo la sintaxis en la parte superior de mi cabeza, pero compruebe si hay memoria compartida sysv. El comando es ipcs, creo.
derobert
55
¿Alguna vez encontraste una solución para esto? - Estoy teniendo un problema similar aquí: superuser.com/questions/793192/...
Hackeron

Respuestas:

4

La memoria en Linux puede ser una bestia extraña para diagnosticar y comprender.

En condiciones normales de funcionamiento, si no todas, su memoria se asignará a una tarea u otra. Algunos se asignarán a los procesos en primer plano que se ejecutan actualmente. Algunos almacenarán datos almacenados en caché del disco. Algunos mantendrán datos asociados con procesos que no se ejecutan activamente en ese momento específico en el tiempo.

Un proceso en Linux tiene su propio espacio de direcciones virtuales (VIRT en la salida de top). Contiene todos los datos asociados con el proceso y puede considerarse cuán "grande" es el proceso. Sin embargo, es raro que toda esa memoria forme parte activa del mapa de memoria "real" (RES en la salida de top). El RES, o memoria residente, son los datos a los que se puede acceder directamente en la RAM en el momento. Luego también hay memoria compartida (SHR) además de eso. Eso se puede compartir entre varias instancias del mismo proceso. Entonces, la memoria en uso por un proceso es en cualquier momento RES + SHR, pero si hay más de una instancia del proceso usando la memoria compartida, el uso es RES más RES más RES ... más SHR.

Entonces, ¿por qué la diferencia entre RES y VIRT? Seguramente si un proceso tiene un bloque de memoria asignada, es memoria asignada, ¿no es así? No. La memoria se asigna en páginas, y las páginas pueden estar activas o inactivas. Los activos son lo que hay en RES. Inactivos son "el resto". Se pueden empujar hacia un lado ya que no se está accediendo en este momento. Eso significa que se pueden intercambiar a disco si la memoria se agota. Pero no solo van directamente al disco. Primero se sientan en un caché. No desea intercambiar todo el tiempo, por lo que hay un búfer entre la aplicación y el espacio de intercambio. Esos búferes cambian constantemente a medida que el intercambiador selecciona un proceso diferente para ejecutar y diferentes páginas se vuelven activas e inactivas. Y todo eso está sucediendo de manera rápida para que un simple ser humano pueda seguir el ritmo.

Y además de todo eso, están los búferes de disco. La memoria inactiva no solo va a una memoria caché, sino que cuando la memoria caché se cambia al disco, primero va a un búfer de disco para ponerla en cola para escribir. Entonces esa es una segunda capa de caché en la mezcla. Y esas memorias intermedias de disco también son utilizadas por otras partes del sistema para la memoria intermedia general de E / S. Así que también están cambiando constantemente.

Entonces, lo que está viendo en cosas como topy freeetc. son instantáneas instantáneas del estado actual de la máquina o estadísticas agregadas durante un período de tiempo. Para cuando haya leído los datos, no están actualizados.

Cualquier proceso puede acceder a grandes cantidades de memoria, pero rara vez es sensato hacerlo. De todos modos, no puede acceder a toda la memoria a la vez, por lo que la memoria que no está viendo actualmente se mueve a la memoria caché a menos que esté marcada específicamente como "bloqueada en el núcleo".

Entonces, la cantidad de memoria "utilizada" por una aplicación y la cantidad de memoria que "tiene" son dos cosas completamente diferentes. Gran parte del espacio de datos de las aplicaciones está realmente en la memoria caché, no en la memoria "central", pero dado que la memoria caché está en la RAM la mayor parte del tiempo está disponible al instante y solo necesita "activarse" para convertirse en memoria "central". Es decir, a menos que se haya intercambiado en el disco, cuando luego necesite ser intercambiado (lo que podría ser rápido si está en el búfer).

Debido a la naturaleza de alta velocidad de la bestia y al hecho de que las cifras siempre están cambiando, los números pueden incluso cambiar en parte al calcular lo que son, por lo que nunca es posible decir exactamente "esta es la cantidad de memoria en uso" La perspectiva de un usuario. El meminfo es una instantánea en el tiempo proporcionada por el kernel, pero dado que es el kernel el que se está ejecutando, no necesariamente muestra el estado real del uso de la memoria de ningún proceso, ya que ningún proceso se está ejecutando activamente en ese momento, es entre procesos.

Como dije, todo es muy confuso.

Pero al final del día realmente no importa. Lo que importa no es la cantidad de memoria que tiene "libre", sino cuánto espacio de intercambio ha utilizado y con qué frecuencia se accede al espacio de intercambio. Es el intercambio lo que ralentiza el sistema, no la falta de memoria (aunque la falta de memoria causa un intercambio excesivo). Si tiene mucha memoria usada, pero no está usando ningún espacio de intercambio (o muy poco), entonces las cosas son normales. La memoria libre en general no es deseable, y a menudo es puramente de transición de todos modos, ya que estaba en uso para un propósito, pero aún no se ha asignado para otro; por ejemplo, era memoria caché y se ha cambiado al disco, pero aún no se ha utilizado para nada más, o fueron buffers de disco, los buffers se han vaciado al disco, pero ninguna aplicación lo ha solicitado para caché todavía.

Majenko
fuente
66
Esto es realmente interesante, pero no responde a la pregunta de por qué el OP está observando esta discrepancia específica.
terdon
Creo que la única discrepancia real radica entre las expectativas de los OP y lo que Linux está proporcionando. Es decir, los valores que da Linux simplemente no cuadran, y eso es porque ya han cambiado.
Majenko
Como el OP realmente no parece entender la pregunta que hace, no veo cómo se puede elegir una respuesta "correcta". Podemos explicar cómo funciona el sistema hasta que estemos azules, pero si no comprende esos conceptos básicos y se da cuenta de que su pregunta no tiene sentido, nunca tendremos una respuesta "correcta".
Majenko
Aprecio por escribir esto, pero sinceramente no me gusta el tono de agnosticismo detrás de esto. Estoy de acuerdo con la teoría de la "instantánea", pero si la instantánea sigue dando el mismo número que dice que el uso de RAM es alto mientras no puede averiguar cómo sucedió, ¿no tendrá curiosidad?
Jason
55
Deberías publicar esto en tu blog. Es bueno, pero no es relevante aquí. Algo extraño está sucediendo (y quiero decir extraño viniendo de alguien que entiende lo que escribiste), ya que los VIRT de los procesos no tienen en cuenta todo el uso de RAM, y el sistema no se intercambia a pesar de la presión para hacerlo.
Gilles 'SO- deja de ser malvado'
0

Esta es una parte de la respuesta:

Hay una diferencia entre lo que se designa como memoria "usada" (en el comando "libre") y "memoria asignada a procesos activos (usuario)" (en / proc / meminfo). Ok, entonces su sistema tiene 48149 MB en total (aproximadamente 47 Gb)

Si mira su / proc / meminfo verá: Inactivo: 17296272 kB = (aproximadamente 16.5 Gb) - La memoria inactiva podría ser de procesos que han terminado. También puede ser memoria que no ha sido utilizada durante mucho tiempo por un proceso que está activo. La memoria no se "libera" solo porque el proceso terminó. ¿Por qué? Porque es más trabajo. La misma página de memoria podría usarse nuevamente, por lo que el kernel de Linux simplemente deja los datos allí en la lista "inactiva" hasta que un proceso lo necesite.

Esta página explica algo de eso. http://careers.directi.com/display/tu/Understanding+and+optimizing+Memory+utilization ; Lea la sección sobre el PFRA (algoritmo de recuperación de marcos de página) utilizado por el kernel de Linux: "Las páginas incluidas en el disco y las memorias caché a las que no hace referencia ningún proceso deben reclamarse antes que las páginas que pertenecen a los espacios de direcciones del modo de usuario de los procesos" "Recuperación" significa moverlos de "usado" (inactivo + activo) a "libre".

Esto explica la gestión de la memoria con más detalle: cómo funcionan las listas activas e inactivas y cómo se mueven las páginas entre ellas https://www.cs.columbia.edu/~smb/classes/s06-4118/l19.pdf

Creo que también hay memoria utilizada por el núcleo para las estructuras de datos, y que esto aparece como "losa 1049464 kb" (~ 1 GB), creo, pero no estoy seguro de que esto se cuente por separado.

ssl
fuente
Solo quería agregar que en el pasado tenía experiencia con un sistema que se estaba quedando sin memoria debido a una aplicación mal escrita que asignaba segmentos de memoria compartida, pero no los liberaba. Los segmentos de memoria compartida persistieron incluso cuando todos los procesos que los usaban murieron. Esto no era Linux, pero también podría ser cierto en Linux. como se mencionó anteriormente, vea ipcs para obtener información sobre esto. vea makelinux.net/alp/035. Dice que necesita desasignar explícitamente la memoria compartida.
ssl
1
No entiendo de qué trata su respuesta, pero "La memoria inactiva podría ser de procesos que han terminado" definitivamente está mal. La memoria de Userland viene en dos sabores: mapeado o anónimo. La memoria asignada siempre se puede recuperar porque los datos se pueden volver a cargar desde un archivo. La memoria anónima puede recuperarse si se intercambia. La memoria inactiva es la memoria que es un buen candidato para reclamar; sin embargo, el contenido debe estar en un archivo o intercambiarse en algún lugar, porque esa memoria todavía está en uso. Cuando un proceso muere, su memoria se libera y ya no se contabiliza en activo + inactivo.
Gilles 'SO- deja de ser malvado'
1
Algunas referencias: ¿Qué puede causar un aumento en la memoria inactiva y cómo recuperarla? en la falla del servidor; consejos viejos pero aún en su mayoría aplicables de Red Hat . Y el artículo de Bhavin Turakhia que también cita; no es explícito al respecto, pero sí explica sobre las páginas anónimas y mapeadas en la sección "Comprensión de la PFRA".
Gilles 'SO- deja de ser malvado'
Pensé en páginas inactivas a las que no hace referencia un proceso de este artículo: kernel.org/doc/gorman/html/understand/understand013.html Aunque supongo que podrían ser páginas liberadas por un proceso que todavía se está ejecutando. sección "Recuperación de páginas de las listas de LRU"
ssl
¿Pero posiblemente eso solo se refiere a páginas en el caché de intercambio?
ssl
-2

¿Usas NFS?
Puede valer la pena correr de slabtop -ocualquier manera, nfs_inode_cachepuede salirse de control.

cjve
fuente
-4

La cifra que debería mirar es el intercambio utilizado , en su salida que es "0", lo que significa que NO se ha quedado sin RAM. Mientras su sistema no esté intercambiando memoria, no debe preocuparse por las otras figuras, que de todos modos son muy difíciles de interpretar.

Editar: Ok, parece que mi respuesta se considera críptica en lugar de concisa. Así que déjame explicarlo.

Supongo que el principal problema aquí es interpretar la salida de top / ps, que no es muy precisa. Por ejemplo, como los múltiples usos de las mismas bibliotecas compartidas no se calculan como cabría esperar, consulte, por ejemplo, http://virtualthreads.blogspot.ch/2006/02/understanding-memory-usage-on-linux.html

Sin embargo, lo que es totalmente exacto es que si el tamaño de intercambio es exactamente cero, entonces su sistema no se quedó sin memoria (todavía). Por supuesto, esa es una declaración muy clara, pero para perfilar el uso de memoria real de sus sistemas, top no será lo correcto. (Y si mira en la parte superior, al menos ordene la salida para virt o% mem.)

Ver también http://elinux.org/Runtime_Memory_Measurement

Echsecutor
fuente
1
No debe preocuparse si su sistema está cambiando tampoco, eso es normal. Debería preocuparse si su sistema se intercambia con demasiada frecuencia (lo que no es lo mismo que tener un gran espacio de intercambio utilizado). El hecho de que el intercambio utilizado sea 0 es extraño en sí mismo, con tan poca memoria física libre.
Gilles 'SO- deja de ser malvado'
bueno, su salida indica que su sistema no hizo ningún intercambio en absoluto. Esa es seguramente la tasa de intercambio óptima. No dije que un tamaño de intercambio pequeño es algo bueno, pero un tamaño cero seguramente lo es. Y mientras el sistema no se quede realmente sin memoria libre, ¿por qué debería comenzar a intercambiarse?
Echsecutor
No, la ausencia de intercambio está lejos de ser óptima. La memoria de los programas que no se están utilizando en este momento debe intercambiarse para dejar espacio en la caché del disco para los archivos de uso frecuente. En cuanto al bit que acaba de agregar sobre la salida de free, creo que quiso decir top, pero incluso entonces la suma solo puede ser más que el total (porque la memoria compartida se cuenta varias veces), no menos.
Gilles 'SO- deja de ser malvado'
¿Qué quieres decir con que la suma solo puede ser más, no menos? la parte superior solo muestra tantos procesos como caben en la pantalla, estoy bastante seguro de que lo anterior no son todos procesos en ejecución, por lo tanto, no están ordenados por el uso de la memoria, esa parte de la salida es bastante inútil para la pregunta 'qué utilizó la memoria' .
Echsecutor
ah, y no quiero entrar en un debate sobre cuándo es el momento óptimo para comenzar a intercambiar, pero el servidor predeterminado de Linux es no intercambiar memoria solo porque "no se está utilizando en este momento".
Echsecutor