Retrouver l'utilisation de la mémoire «manquante» sous Linux

10

Sur un noyau Arch 3.6.7 x86_64 j'essaie de tenir compte de l'utilisation de la mémoire du système, qui plus je le regarde, plus il semble y avoir un trou (dans la comptabilité de la mémoire utilisée, un non-trou dans l'utilisation de).

Il s'agit d'un système fraîchement démarré. Avec pas grand chose en cours d'exécution autre que systemd et sshd pour rester 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

L'information mémoire la plus détaillée que je puisse trouver est celle de 2007, ce qui semble avoir entraîné l'ajout du champ Pss au noyau général représentant un processus, mais leur code python est destiné aux noyaux plus anciens et, malheureusement, à certains des fichiers / proc / k * ont disparu depuis lors. La documentation / proc / meminfo est également utile mais vieillit un peu aussi.

Donc, une démonstration de ce que je vois.

# 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 nous additionnons les utilisés:

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

Tous les actifs * / inactifs * semblent être des compteurs appliqués sur certaines pages (pas toutes) et pourraient donc reproduire ce qui est compté ailleurs.

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

Commited_AS semble ici suivre de près la somme de la mémoire privée / partagée de l'espace utilisateur actualisant les fichiers partagés à partir de / proc / * / smaps. la prise en compte du PSS s'aligne également. (Par intérêt, j'obtiens un Commited_AS beaucoup plus grand sur un debian 32 bits 2.6.32-5-686)

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

La dalle est en ligne avec / proc / slabinfo

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

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

Donc ~ 63M court. Il me semble que le noyau et tous les modules chargés manquent de MB. La dalle semble cependant couvrir beaucoup de choses, donc s'il en manque, je ne sais pas si cela équivaudrait à ~ 60 Mo?

63 est un peu proche de la figure Active + Inactive mais cela ne semble pas correct.

Est-ce que quelqu'un connaît la formule magique ?? Sinon, si les chiffres que je regarde sont les bons, quelles sont les zones grises dans l'allocation de mémoire dans lesquelles je peux fouiller?

Il semble que Linux ait mangé mon bélier! Bien qu'une partie plus petite que celle normalement accusée de =)

edit Commited_AS est une estimation du noyau de la quantité de mémoire dont il aurait besoin pour couvrir 99,9% de ce qu'il a engagé, ce n'est donc pas un vrai nombre alloué. AnonPages + Mapped en fait partie, ce qui laisse un trou plus grand, environ 100 Mo maintenant.

User + Kernel
28368 + 32144 = 60512 != 157036

AnonPages et Mapped suivent principalement les informations anon / mapped de / proc / [0-9] * / smaps wgen en tenant compte de PSS / Shared.

Les zones réservées semblent toutes s'insérer dans le morceau retiré de la mémoire totale:

La freemémoire totale est de 16345032 Ko.
La mémoire système totale est de 16777216 Ko.
«Trou» PCI - lspci -v 266520 Ko = 16510696 Ko
Bios réservés - dmesg 92793 Ko = 16417903 Ko.

edit2 J'ai remarqué que cette utilisation de mémoire supplémentaire n'était pas sur la machine virtuelle exécutée dans la boîte d'origine d'où elle venait/proc/meminfo . J'ai donc commencé à fouiller pour voir ce qui était différent entre les deux. Finalement constaté qu'une augmentation de la mémoire physique totale disponible coïncidait avec l'augmentation de la mémoire utilisée.

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

Cela équivaut à environ 8 Mo alloués pour chaque 1 Go de mémoire. Cela pourrait être une carte mémoire dans le noyau ... mais je pensais que cela ne ferait que croître lorsque la mémoire est allouée plutôt que d'être configurée au démarrage.

Serait intéressant de voir si quelqu'un a accès à des machines bigmem si la tendance se poursuit?

Mat
la source
psse trouve par conception. Ne l'utilisez pas pour la comptabilité de la mémoire.
bahamat
2
acclamations, mais ce n'est pas le décompte ps. C'est une utilisation globale /proc/meminfo. Le seul processus de comptabilité a été via des smaps qui tiennent compte de la mémoire partagée et privée mais c'était uniquement pour se comparer aux valeurs AnonPages / Mapped de meminfo.
Matt
linuxatemyram.com
Hannes Schneidermayer
d'où la référence dans mon article sur Linux mangeant réellement mon bélier =)
Matt

Réponses:

3

La "mémoire utilisée par un processus" n'est pasun concept clair dans les systèmes d'exploitation modernes. Ce qui peut être mesuré est la taille de l'espace d'adressage du processus (SIZE) et la taille de l'ensemble résident (RSS, combien de pages de l'espace d'adressage sont actuellement en mémoire). Une partie de RSS est partagée (la plupart des processus en mémoire partagent une copie de la glibc, et donc pour un assortiment d'autres bibliothèques partagées; plusieurs processus exécutant le même exécutable la partagent, les processus fourchus partagent des données en lecture seule et éventuellement un bloc de données non encore modifiées) lecture-écriture des données avec le parent). D'un autre côté, la mémoire utilisée pour le processus par le noyau n'est pas prise en compte, comme les tables de pages, les tampons du noyau et la pile du noyau. Dans l'image globale, vous devez tenir compte de la mémoire réservée à la carte graphique, de l'utilisation du noyau et des "trous" assortis réservés au DOS et aux autres systèmes préhistoriques (ce n'est pas grand-chose,

La seule façon d'obtenir une image globale est ce que le noyau rapporte en tant que tel. Additionner des nombres avec des chevauchements inconnus et des absents inconnus est un bel exercice d'arithmétique, rien de plus.

vonbrand
la source
1
la «mémoire par processus» n'est pas claire, mais je ne vois pas pourquoi cela devrait affecter le suivi de l'utilisation globale? Pour le noyau, l'ensemble des PageTables, Slab, KernelStack et autres compteurs de non-processus sont signalés dans / proc / meminfo et inclus dans ce que j'essaie de rendre compte (le processus mem semble être là aussi). En plus des compteurs globaux que je cherchais dans les smaps par processus pour la mémoire partagée / privée anon / mappée pour avoir une idée de l'endroit où la mémoire de processus pourrait être prise en compte dans / proc / meminfo. Je vise à savoir quel ensemble de numéros de VM s'ajoute au physique, dans lequel j'ai clairement un trou.
Matt
1
Fondamentalement, psest incapable de tenir correctement compte de la mémoire. Alors ne l'utilisez pas. Quels psrapports ne seraient vrais que si ce processus était le seul en cours d'exécution sur le système (une impossibilité). Pour en savoir plus sur les raisons pour lesquelles vous ne le faites pas, pslisez ici: Comprendre l'utilisation de la mémoire sous Linux
bahamat