Aufspüren der fehlenden Speichernutzung unter Linux

10

Auf einem Arch 3.6.7 x86_64-Kernel versuche ich, die Speichernutzung des Systems zu berücksichtigen. Je mehr ich mir das anschaue, desto mehr scheint es eine Lücke zu geben (in der Abrechnung des verwendeten Speichers eine Lücke) die Verwendung von).

Dies ist ein frisch gebootetes System. Mit nicht viel läuft außer systemd und sshd, um es einfach zu halten

$ 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

Die detaillierteste Speicher Informationen , die ich finden kann dieses aus dem Jahr 2007 , die in der Zugabe des Pss Bereich der allgemeinen Kernel auf die ein Prozess , aber ihre Python - Code ist für ältere Kernel und leider einige der / proc / k * Dateien zur Folge zu haben scheint sind seitdem verschwunden. Die / proc / meminfo- Dokumentation ist ebenfalls hilfreich, altert aber auch ein bisschen.

Also eine Demonstration dessen, was ich sehe.

# 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

Wenn wir die verwendeten addieren:

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

Alle aktiven * / inaktiven * scheinen Zähler zu sein, die auf einige Seiten (nicht alle) angewendet werden, sodass sie duplizieren können, was an anderer Stelle gezählt wird.

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

Commited_AS scheint hier eng an der Summe der privaten / gemeinsam genutzten Speicherbereiche des Benutzerbereichs zu liegen, wobei gemeinsam genutzte Dateien aus / proc / * / smaps abgezinst werden. unter Berücksichtigung von PSS steht auch an. (Aus Interesse bekomme ich ein viel, viel größeres Commited_AS auf einem 32bit Debian 2.6.32-5-686)

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

Die Platte stimmt mit / proc / slabinfo überein

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

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

Also ~ 63M kurz. Es fällt mir auf, dass dem Kernel und allen geladenen Modulen einige MB fehlen. Die Platte scheint jedoch viel zu bedecken. Wenn also etwas fehlt, bin ich mir nicht sicher, ob dies ~ 60 MB entspricht.

63 ist ein bisschen nahe an der Zahl Aktiv + Inaktiv, aber das fühlt sich nicht richtig an.

Kennt jemand die Zauberformel? Ansonsten, wenn die Figur, die ich betrachte, die richtigen sind, in welchen Grauzonen in der Speicherzuordnung kann ich mich umsehen?

Es scheint, Linux hat meinen Widder gefressen! Obwohl ein kleinerer Teil als normalerweise beschuldigt =)

edit Commited_AS ist eine Schätzung des Kernels, wie viel Speicher benötigt wird, um 99,9% des Commits abzudecken. Es handelt sich also nicht um eine echte zugewiesene Zahl. AnonPages + Mapped ist eine Komponente davon, sodass ein größeres Loch verbleibt, das jetzt etwa 100 MB groß ist.

User + Kernel
28368 + 32144 = 60512 != 157036

AnonPages und Mapped verfolgen meistens mit anon / zugeordneten Informationen aus / proc / [0-9] * / smaps wgen unter Berücksichtigung von PSS / Shared.

Die reservierten Bereiche scheinen alle in den Block zu passen, der dem Gesamtspeicher entzogen wurde:

Der Gesamtspeicher freebeträgt 16345032 KB.
Der Gesamtsystemspeicher beträgt 16777216 KB.
PCI-Loch - lspci -v 266520 KB = 16510696 KB BIOS
Reserviert - dmesg 92793 KB = 16417903 KB

edit2 Ich habe festgestellt, dass diese zusätzliche Speichernutzung nicht auf den VMs in der Originalverpackung ausgeführt wird, aus der sie /proc/meminfostammt. Also fing ich an, herumzustöbern und zu sehen, was zwischen den beiden anders war. Schließlich wurde festgestellt, dass eine Zunahme des gesamten verfügbaren physischen Speichers mit der Zunahme des verwendeten Speichers zusammenfiel.

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

Das entspricht einer Zuweisung von ~ 8 MB pro 1 GB Speicher. Könnte eine Speicherzuordnung im Kernel sein ... aber ich dachte, das würde nur wachsen, wenn Speicher zugewiesen wird, anstatt beim Booten eingerichtet zu werden.

Wäre es interessant zu sehen, ob jemand Zugang zu Bigmem-Maschinen hat, wenn sich der Trend fortsetzt?

Matt
quelle
psliegt mit Absicht. Verwenden Sie es nicht für die Speicherabrechnung.
Bahamat
2
Prost, aber das stimmt nicht ps. Es ist die allgemeine Verwendung in /proc/meminfo. Die einzige Prozessabrechnung erfolgte über Smaps, die gemeinsam genutzten und privaten Speicher berücksichtigen, jedoch nur zum Vergleich mit den AnonPages / Mapped-Werten von meminfo.
Matt
linuxatemyram.com
Hannes Schneidermayer
daher der Hinweis in meinem Beitrag über Linux, das tatsächlich meinen RAM isst =)
Matt

Antworten:

3

Der "von einem Prozess verwendete Speicher" ist nichtEin klares Konzept in modernen Betriebssystemen. Was gemessen werden kann, ist die Größe des Adressraums des Prozesses (GRÖSSE) und die Größe des residenten Satzes (RSS, wie viele Seiten im Adressraum sich derzeit im Speicher befinden). Ein Teil von RSS wird gemeinsam genutzt (die meisten Prozesse im Speicher teilen sich eine Kopie von glibc und somit für verschiedene andere gemeinsam genutzte Bibliotheken; mehrere Prozesse, auf denen dieselbe ausführbare Datei ausgeführt wird, teilen sie, Prozesse teilen die Nur-Lese-Daten und möglicherweise einen Teil der noch nicht geänderten Daten Lese- / Schreibdaten mit dem Elternteil). Auf der anderen Seite wird der vom Kernel für den Prozess verwendete Speicher nicht berücksichtigt, wie z. B. Seitentabellen, Kernelpuffer und Kernelstapel. Im Gesamtbild müssen Sie den für die Grafikkarte reservierten Speicher, die Verwendung des Kernels und verschiedene "Löcher" berücksichtigen, die für DOS und andere prähistorische Systeme reserviert sind (das ist nicht viel,

Der einzige Weg, um ein Gesamtbild zu erhalten, ist das, was der Kernel als solches meldet. Das Addieren von Zahlen mit unbekannten Überlappungen und unbekannten Auslassungen ist eine schöne Übung in Arithmetik, nichts weiter.

vonbrand
quelle
1
'Speicher pro Prozess' ist nicht eindeutig, aber ich kann nicht verstehen, warum sich dies auf die Verfolgung der Gesamtnutzung auswirken sollte. Für den Kernel werden die gesamten PageTables-, Slab-, KernelStack- und anderen Nicht-Prozess-Mem-Zähler in / proc / meminfo gemeldet und in dem enthalten, was ich zu berücksichtigen versuche (Process-Mem scheint ebenfalls vorhanden zu sein). Zusätzlich zu den Gesamtzählern, die ich pro Prozess-Smaps für einen nicht zugeordneten, zugeordneten, gemeinsam genutzten / privaten Speicher untersucht habe, um eine Vorstellung davon zu bekommen, wo der Prozessspeicher in / proc / meminfo berücksichtigt werden könnte. Ich ziele darauf ab, welche VM-Nummern sich zu den physischen addieren, in die ich eindeutig ein Loch habe.
Matt
1
Grundsätzlich psist es nicht möglich, den Speicher korrekt zu berücksichtigen. Also benutze es nicht. Welche psBerichte wären nur wahr, wenn dieser Prozess der einzige wäre, der auf dem System ausgeführt wird (eine Unmöglichkeit). Weitere ps
Informationen