Rastreando el uso de memoria "faltante" en Linux

10

En un kernel Arch 3.6.7 x86_64, estoy tratando de dar cuenta del uso de memoria del sistema, que cuanto más lo miro, más parece haber un agujero (en la contabilidad de la memoria usada, un no agujero en el uso de).

Este es un sistema recién arrancado. Con no correr mucho más que systemd y sshd para mantenerlo simple

$ ps aux | sort -n -k6
...
root       316  0.0  0.0   7884   812 tty1     Ss+  14:37   0:00 /sbin/agetty --noclear tty1 38400
matt       682  0.0  0.0  24528   820 pts/0    S+   15:09   0:00 sort -n -k6
dbus       309  0.0  0.0  17280  1284 ?        Ss   14:37   0:00 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
matt       681  0.0  0.0  10808  1364 pts/0    R+   15:09   0:00 ps aux
root       308  0.0  0.0  26060  1516 ?        Ss   14:37   0:00 /usr/lib/systemd/systemd-logind
root       148  0.0  0.0  25972  1692 ?        Ss   14:37   0:00 /usr/lib/systemd/systemd-udevd
matt       451  0.0  0.0  78180  2008 ?        S    14:37   0:00 sshd: matt@pts/0
root       288  0.0  0.0  39612  2708 ?        Ss   14:37   0:00 /usr/sbin/sshd -D
matt       452  0.0  0.0  16452  3248 pts/0    Ss   14:37   0:00 -bash
root         1  0.0  0.0  32572  3268 ?        Ss   14:37   0:00 /sbin/init
root       299  0.0  0.0  69352  3604 ?        Ss   14:37   0:00 /usr/sbin/syslog-ng -F
root       449  0.0  0.0  78040  3800 ?        Ss   14:37   0:00 sshd: matt [priv]
root       161  0.0  0.0 358384  9656 ?        Ss   14:37   0:00 /usr/lib/systemd/systemd-journald

La información de la memoria detallada que puedo encontrar es el de 2007, que parece ser el resultado de la adición del campo Pss al núcleo de contabilidad general para un proceso, pero su código Python es para los núcleos antiguos y por desgracia algunos de los archivos / proc / k * han desaparecido desde entonces La documentación / proc / meminfo también es útil, pero también envejece un poco.

Entonces, una demostración de lo que estoy viendo.

# cat /proc/meminfo
MemTotal:       16345780 kB
MemFree:        16129940 kB
Buffers:           10360 kB
Cached:            48444 kB
SwapCached:            0 kB
Active:            24108 kB
Inactive:          46724 kB
Active(anon):      12104 kB
Inactive(anon):     3616 kB
Active(file):      12004 kB
Inactive(file):    43108 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                 0 kB
Writeback:             0 kB
AnonPages:         11996 kB
Mapped:            16372 kB
Shmem:              3696 kB
Slab:              25092 kB
SReclaimable:      11716 kB
SUnreclaim:        13376 kB
KernelStack:         928 kB
PageTables:         2428 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     8172888 kB
Committed_AS:      34304 kB
VmallocTotal:   34359738367 kB
VmallocUsed:      372788 kB
VmallocChunk:   34359362043 kB
HardwareCorrupted:     0 kB
AnonHugePages:         0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:       12288 kB
DirectMap2M:    16680960 kB

Si sumamos el usado:

MemTotal - MemFree - Buffers - Cached = Used
16345780 - 16129940 - 10360 - 48444 = 157036

Todos los Activos * / Inactivos * parecen ser contadores aplicados sobre algunas páginas (no todas), por lo que podrían duplicar lo que se cuenta en otros lugares.

Active + Inactive = Used
46724  + 24108    = 70832 (not quite)

Commited_AS aquí parece seguir de cerca la suma de espacio de usuario privado / memoria compartida descontando archivos compartidos de / proc / * / smaps. teniendo en cuenta PSS también se alinea. (Por interés obtengo un Commited_AS mucho más grande en un debian de 32 bits 2.6.32-5-686)

AnonPages + Mapped + Commited_AS = Userspace?
11996     + 16372  + 34304       = 62672

Losa está en línea con / proc / slabinfo

Slab +  Shmem + KernelStack + PageTables = Kernelspace?
25092 + 3696  + 928         + 2428       = 32144

Userspace? + Kernelspace? = Used?
62672      + 32144        = 94816

Entonces ~ 63M menos. Me parece que el núcleo y todos los módulos cargados carecen de algunos MB. Sin embargo, la losa parece cubrir mucho, así que si falta algo, no estoy seguro de si eso equivaldría a ~ 60Mb.

63 está un poco cerca de la figura Activa + Inactiva, pero eso no se siente bien.

Entonces, ¿alguien sabe la fórmula mágica? De lo contrario, si las cifras que estoy viendo son las correctas, ¿cuáles son las áreas grises en la asignación de memoria en las que puedo meter?

¡Parece que Linux se comió mi carnero! Aunque una porción más pequeña de lo que normalmente se acusa de =)

edit Commited_AS es una estimación del núcleo de cuánta memoria necesitaría para cubrir el 99.9% de lo que ha comprometido, por lo que no es un número asignado real. AnonPages + Mapped es un componente del mismo, por lo que deja un agujero más grande, alrededor de 100 MB ahora.

User + Kernel
28368 + 32144 = 60512 != 157036

AnonPages y Mapped rastrean principalmente con información anon / mapped de / proc / [0-9] * / smaps wgen teniendo en cuenta PSS / Shared.

Las áreas reservadas parecen encajar todas en la porción que se extrajo de la memoria total:

La freememoria total es 16345032Kb
La memoria total del sistema es 16777216Kb
PCI 'agujero' - lspci -v 266520K = 16510696K BIOS
reservada - dmesg 92793K = 16417903K

edit2 Noté que este uso de memoria adicional no estaba en la máquina virtual que se ejecutaba dentro de la caja original de la que /proc/meminfoera. Así que comencé a hurgar para ver qué era diferente entre los dos. Finalmente se descubrió que un aumento en la memoria física total disponible coincidía con el aumento en la memoria utilizada.

phys 16GB used>144508     vm>50692      user>21500      kern>26428      u+ktot>47928
vm   64MB used>24612      vm>31140      user>14956      kern>14440      u+ktot>29396
vm  256MB used>26316      vm>35260      user>14752      kern>14780      u+ktot>29532
vm    1GB used>33644      vm>35224      user>14936      kern>14772      u+ktot>29708
vm    2GB used>41592      vm>35048      user>14736      kern>15056      u+ktot>29792
vm    4GB used>57820      vm>35232      user>14780      kern>14952      u+ktot>29732
vm    8GB used>82932      vm>36912      user>15700      kern>15388      u+ktot>31088
vm   12GB used>110072     vm>35248      user>14812      kern>15624      u+ktot>30436
vm   15GB used>122012     vm>35424      user>14832      kern>15824      u+ktot>30656

Eso resulta ser ~ 8Mb asignados por cada 1GB de memoria. Podría ser un mapa de memoria en el núcleo ... pero pensé que solo crecería a medida que se asigna memoria en lugar de configurarse en el arranque.

¿Sería interesante ver si alguien tiene acceso a alguna máquina bigmem si la tendencia continúa?

Mate
fuente
psmentiras por diseño. No lo use para la contabilidad de memoria.
bahamat
2
aplausos, pero esto no es contar ps. Es el uso general en /proc/meminfo. El único proceso de contabilidad ha sido a través de smaps que tiene en cuenta la memoria compartida y privada, pero eso fue solo para comparar con los valores AnonPages / Mapped de meminfo.
Matt
linuxatemyram.com
Hannes Schneidermayer
de ahí la referencia en mi publicación sobre Linux realmente comiendo mi carnero =)
Matt

Respuestas:

3

La "memoria utilizada por un proceso" no esUn concepto claro en los sistemas operativos modernos. Lo que se puede medir es el tamaño del espacio de direcciones del proceso (TAMAÑO) y el tamaño del conjunto residente (RSS, cuántas de las páginas del espacio de direcciones están actualmente en la memoria). Parte de RSS se comparte (la mayoría de los procesos en la memoria comparten una copia de glibc, por lo que para una variedad de otras bibliotecas compartidas; varios procesos que ejecutan el mismo ejecutable lo comparten, procesan datos de solo lectura y posiblemente una porción de datos aún no modificados leer y escribir datos con el padre). Por otro lado, la memoria utilizada por Kernel para el proceso no se tiene en cuenta, como las tablas de páginas, los buffers de kernel y la pila de kernel. En la imagen general, debe tener en cuenta la memoria reservada para la tarjeta gráfica, el uso del kernel y una variedad de "agujeros" reservados para DOS y otros sistemas prehistóricos (eso no es mucho,

La única forma de obtener una imagen general es lo que el núcleo informa como tal. Sumar números con superposiciones desconocidas y omisiones desconocidas es un buen ejercicio de aritmética, nada más.

vonbrand
fuente
1
'memoria por proceso' no es claro, pero no puedo ver por qué eso debería afectar el seguimiento del uso general. Para el núcleo, en general, PageTables, Slab, KernelStack y otros contadores de memoria que no son de proceso se informan en / proc / meminfo y se incluyen en lo que estoy tratando de explicar (el proceso de memoria parece estar allí también). Además de los contadores generales que estaba buscando en cada proceso de memoria anon / mapped, shared / private para tener una idea de dónde podría contabilizarse la memoria de proceso en / proc / meminfo. Estoy apuntando a qué conjunto de números de VM se suman al físico, en el que claramente tengo un agujero.
Matt
1
Básicamente pses incapaz de contabilizar correctamente la memoria. Así que no lo uses. Los psinformes solo serían ciertos si ese proceso fuera el único que se ejecuta en el sistema (una imposibilidad). Para obtener más información acerca de por qué no hace eso, pslea aquí: Comprender el uso de memoria en Linux
bahamat