Linux: Total Swap verwendet = Swap von Prozessen verwendet +?

17

Daher versuche ich zu untersuchen, woher die Swap-Nutzung in einem System mit hoher Swap-Nutzung kommt:

# free
             total       used       free     shared    buffers     cached
Mem:        515324     508800       6524          0       4852      27576
-/+ buffers/cache:     476372      38952
Swap:       983032     503328     479704

Aufsummieren des pro Prozess verwendeten Swap:

# for proc in /proc/*; do cat $proc/smaps 2>/dev/null | awk '/Swap/{swap+=$2}END{print swap "\t'`readlink $proc/exe`'"}'; done | sort -n | awk '{total+=$1}/[0-9]/;END{print total "\tTotal"}'
0       /bin/gawk
0       /bin/sort
0       /usr/bin/readlink
28      /sbin/xxxxxxxx
52      /sbin/mingetty
52      /sbin/mingetty
52      /sbin/mingetty
52      /sbin/mingetty
56      /sbin/mingetty
56      /sbin/mingetty
60      /xxxxxxxxxxx
60      /usr/sbin/xxx
84      /usr/sbin/xxx
108     /usr/bin/xxx
168     /bin/bash
220     /sbin/init
256     /sbin/rsyslogd
352     /bin/bash
356     /bin/bash
360     /usr/sbin/sshd
496     /usr/sbin/crond
672     /usr/sbin/sshd
12972   /opt/jdk1.6.0_22/bin/java
80392   /usr/libexec/mysqld
311876  /opt/jdk1.6.0_22/bin/java
408780  Total

Dies ergibt einen niedrigeren Wert für den insgesamt verwendeten Swap. Wo ist der verbleibende genutzte Swapspace? Ist es vmalloc () ed Speicher im Kernel? Etwas anderes? Wie kann ich es identifizieren?

Ausgabe von meminfo:

# cat /proc/meminfo 
MemTotal:       515324 kB
MemFree:          6696 kB
Buffers:          5084 kB
Cached:          28056 kB
SwapCached:     157512 kB
Active:         429372 kB
Inactive:        65068 kB
HighTotal:           0 kB
HighFree:            0 kB
LowTotal:       515324 kB
LowFree:          6696 kB
SwapTotal:      983032 kB
SwapFree:       478712 kB
Dirty:             100 kB
Writeback:           0 kB
AnonPages:      399456 kB
Mapped:           8792 kB
Slab:             7744 kB
PageTables:       1820 kB
NFS_Unstable:        0 kB
Bounce:              0 kB
CommitLimit:   1240692 kB
Committed_AS:  1743904 kB
VmallocTotal:   507896 kB
VmallocUsed:      3088 kB
VmallocChunk:   504288 kB
HugePages_Total:     0
HugePages_Free:      0
HugePages_Rsvd:      0
Hugepagesize:     4096 kB
Ninj
quelle
Puffer und Cache sind enthalten und sie sind keinem Prozess zugeordnet.
Goldlöckchen
2
@goldilocks: nein, die sind im physischen Speicher. Sie summieren sich auch nicht.
Ninj
Du hast recht, ich denke, Sachen zwischenzuspeichern, um sie zu tauschen, wäre irgendwie sinnlos. Ich denke jedoch, dass ausgelagertes Material dort belassen und nachverfolgt werden kann, auch wenn der Prozess, dessen Eigentümer es ist, nicht mehr funktioniert, solange dieser Swap-Bereich nicht anderweitig benötigt wird. Dies spart später Zeit, wenn ein Prozess dieselbe Seite lädt und diese Seite dann erneut ausgetauscht werden muss - sie ist noch immer im Swap-Modus vorhanden. Google "Swap-Cache" linux-tutorial.info/modules.php?name=MContent&pageid=314 Dies entspricht dem tatsächlichen "Cache-Cache" (es handelt sich um im Arbeitsspeicher gespeichertes Material aus nicht mehr funktionierenden Prozessen).
Goldlöckchen
... was bedeutet, lol, dass das "Cachen von Sachen im Swap" nicht so sinnlos ist, nur dass es nicht dort ankommt, indem man den RAM-Cache auslagert.
Goldlöckchen
1
Ist die Antwort nicht einfach, dass der Kernel tauschen kann und das nicht in Ihrer Verarbeitung enthalten ist? Insbesondere der Kernel hat heutzutage einen Haufen von "User Space" -Prozessen ... Nur eine überlegte Vermutung.
iain

Antworten:

11

Der Unterschied, den Sie beobachten, ist nicht darauf zurückzuführen, dass der Swap-Bereich nicht berücksichtigt wird. Das "(gelöscht)", das der Kernel manchmal an /proc/*/exeLinks anfügt, wird von ausgegeben readlinkund verursacht Analysefehler in Ihrem awk-Skript, und Sie zählen effektiv keine Prozesse, deren Binärdateien in Ihrer Gesamtzahl nicht mehr vorhanden sind.

Einige Kernel hängen das Wort "(gelöscht)" an /proc/*/exeSymlink-Ziele an, wenn die ursprüngliche ausführbare Datei für den Prozess nicht mehr vorhanden ist.

Der Grund, warum Ihr Befehl weniger als die Gesamtsumme anzeigt, ist der folgende. Die Ausgabe von readlinkauf solchen Links wird so etwas wie "/ path / to / bin (deleted)" sein, was einen Analysefehler verursacht, awkwenn die Ausgabe wieder in den String eingesetzt wird (Klammern und Leerzeichen gefallen ihm nicht). Führen Sie zum Beispiel Folgendes aus:

for a in /proc/*/exe ; do readlink $a ; done | grep deleted

Und Sie werden ein paar Einträge mit dem Zusatz "(gelöscht)" sehen. Wenn Sie sich die Auslagerungsnutzung für diese Einträge ansehen, würde ihre Summe der angezeigten Diskrepanz entsprechen, da die resultierenden awkFehler verhindern, dass ihre Gesamtsummen berechnet und in die Endsumme einbezogen werden.

Wenn Sie Ihren ursprünglichen Befehl ausführen, ohne stderr irgendwo umzuleiten, werden Sie wahrscheinlich einige "runaway string constant" -Fehler bemerken. Diese Fehler sind das Ergebnis der oben genannten und Sie sollten sie nicht ignoriert haben.

Wenn Sie andere mögliche Verbesserungen an Ihrem ursprünglichen Befehl ignorieren, können Sie diesen ändern, indem Sie das "(gelöscht)" wie folgt entfernen (Anmerkung |awk '{print $1}'zur readlinkAusgabe hinzugefügt ):

for proc in /proc/*; \
  do cat $proc/smaps 2>/dev/null | awk '/Swap/{swap+=$2}END{print swap "\t'`readlink $proc/exe|awk '{print $1}' `'" }'; \
done | sort -n | awk '{total+=$1}/[0-9]/;END{print total "\tTotal"}'

Diese Verwendung von awk, um die Ausgabe von zu korrigieren, readlinkkann zu Fehlern führen, wenn der Name Leerzeichen enthält. Sie können eine sedbeliebige Methode verwenden.

Bonus Info

Übrigens könnten Sie nur verwenden smem -t. In der Spalte "Tauschen" wird angezeigt, was Sie möchten.

Sie können diese Informationen jedoch auch direkt aus dem VmSwapFeld in /proc/*/statusabrufen (smaps erfordert eine gewisse Kernelunterstützung und ist nicht immer verfügbar) und vermeiden, dass Sie die Fehlerausgabe umleiten müssen, indem Sie ein geeignetes Dateinamenmuster verwenden, das das vermeidet Fehler zu Beginn:

for proc in /proc/[0-9]*; do \
  awk '/VmSwap/ { print $2 "\t'`readlink $proc/exe | awk '{ print $1 }'`'" }' $proc/status; \
done | sort -n | awk '{ total += $1 ; print $0 } END { print total "\tTotal" }'

Wenn Sie die eigentliche Binärdatei nicht benötigen und sich nur mit dem Prozessnamen befassen können, erhalten Sie alles von status:

for a in /proc/*/status ; do \
  awk '/VmSwap|Name/ { printf $2 " " } END { print "" }' $a ; \
done | awk '{ total+=$2 ; print $0 } END { print "Total " total }'

Und schließlich, wenn nur die PIDs ausreichen, können Sie alles einfach mit awk:

awk '/VmSwap/ { total += $2; print $2 "\t" FILENAME } END { print total "\tTotal" }' /proc/*/status

Hinweis:

Das soll nicht heißen, dass es keine Unterschiede zwischen freeund gibt smem(letzteres ist dasselbe wie Ihr Skript). Es gibt viele davon (siehe zum Beispiel https://www.google.com/search?q=smem+free , das auf der ersten Seite mehr als genug Ergebnisse liefert, um Ihre Fragen zur Speichernutzung zu beantworten). Ohne einen geeigneten Test kann Ihre spezifische Situation jedoch nicht angegangen werden.

Jason C
quelle
5

Swap wird auch von den tmpfs verwendet, wenn der Kernel mehr freien Arbeitsspeicher benötigt oder einfach, weil er einige Zeit nicht verwendet wird. Daher kann jede Verwendung von tmpfs Swap verbrauchen.

Higuita
quelle
1
Warum die Gegenstimme? Das ist absolut richtig.
Juli