929 Stimmen

Wie kann ich den tatsächlichen Speicherverbrauch einer Anwendung oder eines Prozesses messen?

Wie misst man den Speicherverbrauch einer Anwendung oder eines Prozesses in Linux?

In dem Blog-Artikel von Understanding memory usage on Linux ist ps kein genau richtiges Tool für diesen Zweck.

Warum ps "falsch" ist

Je nachdem, wie man es betrachtet, meldet ps nicht den tatsächlichen Speicherverbrauch von Prozessen. Was es wirklich tut, ist zu zeigen, wie viel echten Speicher jeder Prozess einnehmen würde, wenn er der einzige laufende Prozess wäre. Natürlich hat eine typische Linux-Maschine zu jedem beliebigen Zeitpunkt mehrere Dutzend Prozesse laufen, was bedeutet, dass die von ps gemeldeten VSZ- und RSS-Zahlen fast sicher falsch sind.

(Hinweis: Diese Frage wird <a href="https://stackoverflow.com/q/63166/15161">hier</a> sehr ausführlich behandelt.)

11 Stimmen

Diese Frage gehört wahrscheinlich heutzutage eher auf serverfault.com, obwohl es mir sagt, dass sie "zu alt zum Migrieren" ist. Möchte es allerdings nicht wirklich scließen...

0 Stimmen

Beziehen Sie sich auf diese Frage. stackoverflow.com/questions/669438/…

4 Stimmen

Tatsächlich zeigt ps nicht einmal das - es zeigt virtuelle und residente Speicherzahlen, wobei virtuelle die maximale Menge an Speicher ist, die der Prozess theoretisch nutzen könnte, wenn er der einzige Prozess wäre (niemals so), jede einzelne Seite, die er allokiert hat, verwendet (nie passiert) und keine Seiten abbildet oder abbildet oder entmappen (unwahrscheinlich). Während residente anzeigt, wie viel virtueller Speicher gerade physisch zugeordnet ist. Normalerweise virt > Nutzung > res jedoch auf einem 64-Bit-System virt ~= res*10 ist es eine sehr große Bandbreite.

29voto

GypsyCosmonaut Punkte 499

Ich benutze Arch Linux und es gibt dieses wunderbare Paket namens ps_mem:

ps_mem -p 

Beispiel Ausgabe

$ ps_mem -S -p $(pgrep firefox)

Privat   +   Geteilt  =  Genutzter RAM   Genutzter Swap   Programm

355,0 MiB +  38,7 MiB = 393,7 MiB    35,9 MiB   firefox
---------------------------------------------
                        393,7 MiB    35,9 MiB
=============================================

0 Stimmen

ps_mem sieht gut aus und ist auch auf CentOS verfügbar :-)

4 Stimmen

Dieses Skript ist absolut erstaunlich. Macht genau das, was ich brauchte. Sie können es schnell und einfach auf Ubuntu mit diesem langen, aber einfachen Befehl erhalten, falls Sie es benötigen: sudo curl -sL https://raw.githubusercontent.com/pixelb/ps_mem/master/ps_me‌​m.py -o /usr/local/bin/ps_mem.py; sudo chmod 755 /usr/local/bin/ps_mem.py; sudo apt install python -y -qq; sudo ps_mem.py

0 Stimmen

Heutzutage möchten Sie wahrscheinlich smem -k verwenden.

23voto

Dprado Punkte 1550

Es gibt keine eindeutige Antwort darauf, weil man den genauen Speicherbedarf eines Prozesses nicht genau bestimmen kann. Die meisten Prozesse unter Linux verwenden gemeinsam genutzte Bibliotheken.

Zum Beispiel, nehmen wir an, du möchtest den Speicherverbrauch für den Prozess 'ls' berechnen. Zählst du nur den Speicher, der vom ausführbaren 'ls' verwendet wird (wenn du ihn isolieren könntest)? Wie sieht es mit libc aus? Oder all diesen anderen Bibliotheken, die benötigt werden, um 'ls' auszuführen?

linux-gate.so.1 => (0x00ccb000)
librt.so.1 => /lib/librt.so.1 (0x06bc7000)
libacl.so.1 => /lib/libacl.so.1 (0x00230000)
libselinux.so.1 => /lib/libselinux.so.1 (0x00162000)
libc.so.6 => /lib/libc.so.6 (0x00b40000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00cb4000)
/lib/ld-linux.so.2 (0x00b1d000)
libattr.so.1 => /lib/libattr.so.1 (0x00229000)
libdl.so.2 => /lib/libdl.so.2 (0x00cae000)
libsepol.so.1 => /lib/libsepol.so.1 (0x0011a000)

Man könnte argumentieren, dass sie von anderen Prozessen gemeinsam genutzt werden, aber 'ls' kann nicht auf dem System ausgeführt werden, ohne dass sie geladen sind.

Außerdem, wenn du wissen möchtest, wie viel Speicher ein Prozess für die Kapazitätsplanung benötigt, musst du berechnen, wie viel jeder zusätzliche Kopie des Prozesses verbraucht. Ich denke /proc/PID/status könnte dir genügend Informationen über den Speicherverbrauch zu einem bestimmten Zeitpunkt geben. Andererseits wird dir Valgrind ein besseres Profil des Speicherverbrauchs über die Lebensdauer des Programms geben.

0 Stimmen

Ich versuche herauszufinden, wie viel Speicher ein Prozess auf einer VM in Anspruch nimmt und möchte das nutzen, um ein Speicherlimit in Kubernetes festzulegen. Ich stimme dieser Antwort zu, deshalb werde ich den vom pmap angezeigten Speicher verwenden.

19voto

CashCow Punkte 29849

Wenn Ihr Code in C oder C++ ist, könnten Sie getrusage() verwenden, das Ihnen verschiedene Statistiken über Speicher- und Zeitnutzung Ihres Prozesses liefert.

Nicht alle Plattformen unterstützen dies jedoch und geben für die Speichernutzungsoptionen 0-Werte zurück.

Stattdessen können Sie die virtuelle Datei unter /proc/[pid]/statm (wo [pid] durch Ihre Prozess-ID ersetzt wird. Diese können Sie mit getpid() erhalten) betrachten.

Diese Datei wird wie eine Textdatei mit 7 ganzen Zahlen aussehen. Sie sind wahrscheinlich am meisten an der ersten (gesamte Speichernutzung) und sechsten (Datenspeichernutzung) Nummer in dieser Datei interessiert.

0 Stimmen

Bitte beachten Sie, dass dies nicht auf allen Plattformen unterstützt wird.

0 Stimmen

Laut der Linux-Man-Seite (linux.die.net/man/2/getrusage) ist getrusage Teil der SVr4-, 4.3BSD- und POSIX.1-2001-Spezifikationen (wobei POSIX nur die utime- und stime-Felder spezifiziert.) Ich würde nicht erwarten, dass es auf Nicht-UNIX-Plattformen funktioniert (außer vielleicht über eine Umgebung wie Cygwin, die UNIX-Funktionen für andere Plattformen bereitstellt.)

0 Stimmen

@DavidC. Der Fragesteller fragt nach Linux.

15voto

Thomas Shaiker Punkte 141

Drei weitere Methoden, die Sie ausprobieren können:

  1. ps aux --sort pmem
    Es sortiert die Ausgabe nach %MEM.
  2. ps aux | awk '{print $2, $4, $11}' | sort -k2r | head -n 15
    Es sortiert mit Pipes.
  3. top -a
    Es startet das Sortieren von top nach %MEM

(Aus hier extrahiert)

3 Stimmen

oben und wahrscheinlich die anderen geben keine genaue Darstellung des tatsächlich vom Prozess verwendeten Speichers. Zum Beispiel habe ich 64GiB RAM und ich habe 10 postgres Prozesse, von denen jeder 16GiB RES und 25% MEM angibt. Natürlich können sie nicht alle 25% nutzen... Jeder hat auch 15GiB SHR und es scheint, dass sie das teilen.

0 Stimmen

Wie beantwortet dies die Frage? Die Prämisse war: "ps ist kein genaues Werkzeug, um dies zu verwenden."

14voto

holmes Punkte 776

Valgrind kann detaillierte Informationen anzeigen, aber es verlangsamt die Zielanwendung erheblich und ändert meistens das Verhalten der Anwendung.

Exmap war etwas, das ich noch nicht kannte, aber anscheinend benötigen Sie ein Kernelmodul, um die Informationen zu erhalten, was ein Hindernis sein kann.

Ich gehe davon aus, dass alle mit "Speicherverbrauch" Folgendes wissen möchten... In Linux kann der physikalische Speicher, den ein einzelner Prozess verwenden könnte, in folgende Kategorien grob unterteilt werden.

  • M.a anonymer kartierter Speicher

  • .p privat

    • .d dirty == malloc/mmapped-Heap und Stack allozierter und beschriebener Speicher
    • .c clean == einmal allozierter, beschriebener und dann freigegebener, aber noch nicht zurückgewonnener malloc/mmapped-Heap- und Stack-Speicher
  • .s gemeinsam genutzt

    • .d dirty == malloc/mmaped-Heap könnte kopiert und gemeinsam von Prozessen genutzt werden (bearbeitet)
    • .c clean == malloc/mmaped-Heap könnte kopiert und gemeinsam von Prozessen genutzt werden (bearbeitet)
  • M.n benannter kartierter Speicher

  • .p privat

    • .d dirty == Datei mmapped beschriebener privater Speicher
    • .c clean == kartierter Programm-/Bibliothekstext privater kartierter Speicher
  • .s gemeinsam genutzt

    • .d dirty == Datei mmapped beschriebener gemeinsamer Speicher
    • .c clean == kartierter Bibliothekstext gemeinsam kartierter Speicher

Das in Android enthaltene Dienstprogramm showmap ist sehr nützlich

virtual                    shared   shared   private  private
size     RSS      PSS      clean    dirty    clean    dirty    object
-------- -------- -------- -------- -------- -------- -------- ------------------------------
       4        0        0        0        0        0        0 0:00 0                  [vsyscall]
       4        4        0        4        0        0        0                         [vdso]
      88       28       28        0        0        4       24                         [stack]
      12       12       12        0        0        0       12 7909                    /lib/ld-2.11.1.so
      12        4        4        0        0        0        4 89529                   /usr/lib/locale/en_US.utf8/LC_IDENTIFICATION
      28        0        0        0        0        0        0 86661                   /usr/lib/gconv/gconv-modules.cache
       4        0        0        0        0        0        0 87660                   /usr/lib/locale/en_US.utf8/LC_MEASUREMENT
       4        0        0        0        0        0        0 89528                   /usr/lib/locale/en_US.utf8/LC_TELEPHONE
       4        0        0        0        0        0        0 89527                   /usr/lib/locale/en_US.utf8/LC_ADDRESS
       4        0        0        0        0        0        0 87717                   /usr/lib/locale/en_US.utf8/LC_NAME
       4        0        0        0        0        0        0 87873                   /usr/lib/locale/en_US.utf8/LC_PAPER
       4        0        0        0        0        0        0 13879                   /usr/lib/locale/en_US.utf8/LC_MESSAGES/SYS_LC_MESSAGES
       4        0        0        0        0        0        0 89526                   /usr/lib/locale/en_US.utf8/LC_MONETARY
       4        0        0        0        0        0        0 89525                   /usr/lib/locale/en_US.utf8/LC_TIME
       4        0        0        0        0        0        0 11378                   /usr/lib/locale/en_US.utf8/LC_NUMERIC
    1156        8        8        0        0        4        4 11372                   /usr/lib/locale/en_US.utf8/LC_COLLATE
     252        0        0        0        0        0        0 11321                   /usr/lib/locale/en_US.utf8/LC_CTYPE
     128       52        1       52        0        0        0 7909                    /lib/ld-2.11.1.so
    2316       32       11       24        0        0        8 7986                    /lib/libncurses.so.5.7
    2064        8        4        4        0        0        4 7947                    /lib/libdl-2.11.1.so
    3596      472       46      440        0        4       28 7933                    /lib/libc-2.11.1.so
    2084        4        0        4        0        0        0 7995                    /lib/libnss_compat-2.11.1.so
    2152        4        0        4        0        0        0 7993                    /lib/libnsl-2.11.1.so
    2092        0        0        0        0        0        0 8009                    /lib/libnss_nis-2.11.1.so
    2100        0        0        0        0        0        0 7999                    /lib/libnss_files-2.11.1.so
    3752     2736     2736        0        0      864     1872                         [heap]
      24       24       24        0        0        0       24 [anon]
     916      616      131      584        0        0       32                         /bin/bash
-------- -------- -------- -------- -------- -------- -------- ------------------------------
   22816     4004     3005     1116        0      876     2012 TOTAL

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X