Frage

Ich versuche, die Speicherverwendung eines Prozesses (Java -Programm) unter Linux zu messen und habe zwei Fragen zu diesem Thema:

  1. Ich habe versucht, das Skript zu verwenden ps_mem.py(SUMS -Werte aus/proc/$ pID/smaps) und der Spitzenwert der Gesamtspeicherverwendung betrug etwa 135 MB (privater und gemeinsamer Speicher). Die Menge des gemeinsamen Speichers beträgt weniger als 1 MB. Versuch, Valgrind mit dem Massiv -Werkzeug zu verwenden valgrind --tool=massif --trace-children=yes --stacks=yes java myProgram Ergibt sich auf den Höhepunkt des Speicherverbrauchs ca. 10 MB.
    So wie ich es verstehe, werden die Variablen meines Programms auf Heap gespeichert. Bedeutet dies, dass der Unterschied zwischen den beiden Methoden der von dem Code selbst genommene Raum (einschließlich JVM) ist?

  2. Verwendet das gleiche Programm unterschiedliche Speichermenge auf verschiedenen Maschinen, wenn sie eine unterschiedliche Menge an RAM oder/und unterschiedliche Prozessoren verwenden (ARM oder X86)?

War es hilfreich?

Lösung

  1. Beruht.
    • Viele der gemeinsamen Speicherzuordnungen in smaps werden direkt durch Bibliotheken/Binärdateien auf der Festplatte gesichert. Während der Fußabdruck dieser wichtiger ist, ist es weniger wichtig, da das System diese Seiten jederzeit fallen lassen und sie bei Bedarf von der Festplatte neu laden kann.
    • Alles, was schmutzig oder privat ist, gehört ausschließlich zum aktuellen Prozess (gut, verarbeiten Sie Baum, wenn Ihr Programm ohne Execs vorliegt). Dies ist wichtiger, da das System sie zum Tausch speichern muss, wenn es diese Seiten aus dem Gedächtnis schieben muss.
    • Was MASSIF misst, ist wahrscheinlich mit letzterem korreliert. Der von der JVM selbst (ohne Ihr Programm) erstellte Speicher ist jedoch in beiden.
  2. Ja. Java oder eine Bibliothek, die sie verwendet, kann sein Speichermodell je nach Größe des verfügbaren RAM anpassen. Auf einer anderen Architektur verwenden Sie völlig unterschiedliche Binärdateien, die möglicherweise größer oder kleiner oder unterschiedlich angeordnet sind oder unterschiedliche Strategien für JIT und Speicherverwaltung verwenden.

Andere Tipps

Es gibt eine ähnliche Frage als dies und beantwortet das Gleiche hier, um die Leute darüber zu informieren, wie linux proc -stat vm -Informationen derzeit nicht korrekt ist.
Valgrind kann detaillierte Informationen anzeigen, verlangsamt jedoch die Zielanwendung erheblich und ändert die meiste Zeit das Verhalten der App.

Ich nehme an, was jeder wissen möchte, dass die "Gedächtnisnutzung" der folgende ist ...
Unter Linux kann die Menge an physischem Speicher, die ein einzelner Prozess verwendet, in etwa in folgende Kategorien unterteilt werden.

  • MA Anonymous Maped Memory
    • .p privat
      • .d Dirty == malloc/mmapped Heap und Stack zugewiesen und geschriebener Speicher
      • .c clean == malloc/mmapped Heap und Stapelspeicher, sobald sie zugewiesen, geschrieben, dann befreit, aber noch nicht zurückgewiesen wurden
    • .s geteilt
      • .d schmutzig == Es sollte keine geben
      • .c clean == Es sollte keine geben
  • MN namens Kartierspeicher
    • .p privat
      • .d Dirty == Datei MMADD Schrift
      • .c Clean == Programm/Bibliothek Text privat zugeordnet
    • .s geteilt
      • .d Dirty == Datei MMADD Schrift
      • .c sauber == zugeordnete Bibliothekstext geteilt zugeordnet

Ich würde es vorziehen, die Zahlen wie folgt zu erhalten, um die realen Zahlen im geringsten Overhead zu erhalten.
Sie müssen diese zusammenfassen, um zu teilen, was PS als RSS zeigt, und genauere Zahlen zu erhalten, die Sie nicht verwirren können.
/Proc/(PID)/Status versucht, diese Zahlen anzuzeigen, aber sie versagen.
Anstatt zu versuchen, [Anon], [Stack] zu kennzeichnen, korrekt für jede Zuordnung kennzeichnet, ist mein Wunsch, dass Linux -Kernel -Personen den Proc -Eintragscode für die Summe und die Anzeige dieser MAPD, MAPC, MNPD, .... Zahlen den Mainline machen.
Eingebettete Linux -Leute werden wirklich glücklich imho.

MAPD:

 awk '/^[0-9a-f]/{if ($6=="") {anon=1}else{anon=0}} /Private_Dirty/{if(anon) {asum+=$2}else{nasum+=$2}} END{printf "sum=%d\n",asum}' /proc/<pid>/smaps

MAPC:

 awk '/^[0-9a-f]/{if ($6=="") {anon=1}else{anon=0}} /Private_Clean/{if(anon) {asum+=$2}else{nasum+=$2}} END{printf "sum=%d\n",asum}' /proc/<pid>/smaps

MNPD: ... und so weiter

Für #1 ist der gemeinsame Speicher (potenziell) von mehr als einem Prozess verwendet. Dies ist im Grunde genommen, wenn Sie dieselbe binäre Datei in mehreren Prozessen ausführen oder verschiedene Prozesse eine gemeinsam genutzte Bibliothek verwenden. In dem Haufen wird zugewiesener Speicher gespeichert (wenn Sie verwenden new in Java). Da Java seine VM hat, vergeben er viel Speicher auf der Prozessstufe, die Sie in Ihrem Java -Code nicht sehen. Ich denke, die Mehrheit dieser 135 MB stammt aus dem JVM -Code/den Daten selbst. Es wird jedoch auch der Speicher, der vom Stapel (wenn Sie einen Funktionsaufruf tätigen und lokale Variablen haben), genommen werden.

Für #2 würde sich eine unterschiedliche Menge an RAM nicht auswirken, wie viel "Speicher" verwendet wird, wenn wir den Speicher des Speichers gleichermaßen auf dem RAM + -Schap -Speicherplatz lassen. Verschiedene Prozessoren (insbesondere, wenn wir über 32-Bit gegenüber 64-Bit sprechen) können eine unterschiedliche Menge an Speicher verwenden. Außerdem kann die Art und Weise, wie ein Prozess zusammengestellt wird, die verwendete Speichermenge ändern, da Sie einen Compiler anweisen können, für den Speicher Fußabdruck über die Geschwindigkeit zu optimieren und einige oder alle Optimierungen insgesamt zu deaktivieren.

Vielleicht möchten Sie sich JConsole ansehen. Die Dinge können je nach Zweck Ihrer Messung schwierig sein. Wenn Sie die Speicherverwendung Ihres Java -Programms kennen möchten, sind Tools, die die Speicherverwendung eines Prozesses messen, ungenau, da sie den Speicher des JVM sowie Ihres Programms anzeigen.

Was das Massiv -Tool betrifft, sollten Sie wissen, dass Teile des JVM auf dem Stapel gespeichert werden und der Java -Code selbst auf dem Haufen steht (da es sich um eine Variable des JVM handelt), weiß ich nicht genug über die JVM zu sagen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top