Speicherverbrauch einzelner Anwendungen unter Linux

Unter Linux gibt es viele Tools um sich den Speicherverbrauch der laufenden Prozesse anzeigen zulassen. Ein Beispiel hierfür ist das Tool ps. Doch eines haben diese Tools gemeinsam, sie zeigen nie den "wirklichen" Speicherverbrauch an.

Ruft man ps wie folgt auf, so werden zu jedem Laufenden Prozess weitere Informationen angezeigt.

$ ps aux

Betrachten wir an dieser Stelle das Programm gedit. Stark verkürzt würde die Ausgabe von ps aux für dieses Programm so aussehen.

$ ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
user     24170  0.0  1.6  46156 16820 ?        S    12:50   0:01 gedit

Wichtige Angaben sind hierbei PID, VSZ und RSS.

PID ist die Prozess ID, welche einmalig ist. Sprich sie kommt zum gleichen Zeitpunkt nicht doppelt im System vor und mit ihr kann ein Prozess eindeutig identifiziert werden.

VSZ steht für "virtual set size", was die Virtuelle Größe des Programms ist.

RSS steht für "resident set size", was die Summe aus der Größe des Codes und der Größe der Daten ist.

Fälschlicher Weise werden die beiden Angaben VSZ und RSS meist als Speicherbedarf eines Programms angegeben. Was einen enormen Speicherverbrauch von ca. 46 MByte bzw. ca. 17 MByte bedeuten würde.

Jedoch sagen diese beiden Größen nur aus, wie viel Speicher die Anwendung brauchen würde, wenn sie alleine auf dem System läuft. Was jedoch selten der Fall ist.

Wo kommen also die großen Werte für den Speicherverbrauch her?

Unter vielen Betriebssystem gibt es das Konzept von so genannten "Shared Libraries". Diese Bibliotheken werden meist von vielen Programmen benutzt. Der Vorteil daran ist jedoch, dass der Code und die Daten der Bibliothek nur einmal in den RAM geladen wird und allen Programmen zur Verfügung steht.

Und genau dieser Speicher wird auch in die beiden Werte VSZ und RSS mit eingerechnet.

Doch wie kann nun der "echte" Speicherverbrauch einer Anwendung bestimmt werden?

Dazu kann das Programm pmap verwendet werden. Welches wie folgt aufgerufen wird.

$ pmap -d

In unserem Fall müsste es also mit folgender Eingabe aufgerufen werden.

$ pmap -d 24170

Als Ausgabe erscheint nun folgendes. Die Ausgabe habe ich an dieser Stelle wieder stark gekürzt und kann von System zu System leicht variieren.

$ pmap -d 24170
24170:   gedit
Address   Kbytes Mode  Offset           Device    Mapping
08048000     576 r-x-- 0000000000000000 0fe:00000 gedit
080d8000      16 rw--- 000000000008f000 0fe:00000 gedit
b6bb9000      12 r-x-- 0000000000000000 0fe:00000 libgpg-error.so.0.3.0
b6bbc000       4 rw--- 0000000000002000 0fe:00000 libgpg-error.so.0.3.0
b6bbd000     300 r-x-- 0000000000000000 0fe:00000 libgcrypt.so.11.2.3
b6c08000       8 rw--- 000000000004a000 0fe:00000 libgcrypt.so.11.2.3
b6c0a000      60 r-x-- 0000000000000000 0fe:00000 libtasn1.so.3.0.12
b6c19000       4 rw--- 000000000000e000 0fe:00000 libtasn1.so.3.0.12
b6c54000     764 r-x-- 0000000000000000 0fe:00000 libasound.so.2.0.0
b6d13000      16 rw--- 00000000000be000 0fe:00000 libasound.so.2.0.0
b6d17000      16 r-x-- 0000000000000000 0fe:00000 libORBitCosNaming-2.so.0.1.0
b7f55000     104 r-x-- 0000000000000000 0fe:00000 ld-2.7.so
b7f6f000       8 rw--- 0000000000019000 0fe:00000 ld-2.7.so
bf9e0000      84 rw--- 00000000bffeb000 000:00000   [ stack ]
mapped: 46156K    writeable/private: 5628K    shared: 756K

Bei dieser Ansicht kann leicht zwischen Daten und Code unterschieden werden. Der Wert r-x-- in der Mode Spalte bedeutet, dass es sich um Code handelt. Im Gegensatz dazu steht die Angabe rw---, welche Daten kennzeichnet.

Unser Interesse liegt jedoch besonders auf dem Speicherverbrauch der einzelnen Komponenten. Dazu muss die zweite und die sechste Spalte betrachtet werden. In letzterer kann die Komponente abgelesen werden und in ersterer der Spicherverbrauch dieser. Steht dort zum Beispiel libgpg-error.so.0.3.0 so wird der Speicher von der "Shared Library" libgpg-error verwendet. In diesem Fall 12 KByte Code und 4 KByte Daten.

Nach dem Überfliegen der Tabelle ist schnell festzustellen, dass der meiste Speicher durch "Shared Libraries" benutzt wird.

Um nun zu bestimmen wieviel Speicher das Programm gedit wirklich benötigt, dürfen nur die Speicherbereiche betrachtet werden, welche nicht von "Shared Libraries" verwendet werden. Wurde dies gemacht, sollte das Ergebnis dem Wert bei "writeable/private" entsprechen.

In diesem Fall sind das 5628 KByte. Das Programm gedit belegt also in Wirklichkeit nur ca. 5,6 MByte des Arbeitsspeichers.

Diese Angabe ist jedoch mit Vorsicht zu betrachten. Wird zum Beispiel gedit, was eine GTK+ Anwendung ist, unter KDE gestartet und läuft keine weitere GTK+ Anwendung, dann werden die GTK+ Bibliotheken exklusiv von diesem Programm verwendet. Was bedeutet, dass die Größe der "Shared Libraries" mit in die Größe des Programms eingerechnet werden müssen.

Weitere Informationen sind in den entsprechenden Manpages zu finden, welche wie folgt aufgerufen werden können.

$ man ps
$ man pmap

Verwandte Artikel