Ich muss die Speichermenge überwachen, die von Threads verbraucht wird, die von meiner Anwendung erzeugt werden. Die Idee ist, Korrekturmaßnahmen zu ergreifen, wenn ein gieriger Thread zu viel Speicher verbraucht. Ich habe auf Wie viel Speicher benötigt mein Java-Thread? . Einer der Vorschläge für diesen Link ist die Verwendung von getThreadAllocatedBytes
in ThreadMXBean.
Ich habe mit getThreadAllocatedBytes
mit dem folgenden Job experimentiert.
Ich führe diesen Job für längere Zeit auf vier Threads aus. Obwohl der Job nicht ständig Speicher akkumuliert, steigen die von getThreadAllocatedBytes
zurückgegebenen Werte weiter an und fallen nicht einmal ab. Dies bedeutet, dass getThreadAllocatedBytes
nicht die tatsächliche Speichermenge auf dem vom Thread verwendeten Heap zurückgibt. Sie gibt die Gesamtspeichermenge zurück, die seit dem Start für den Thread auf dem Heap reserviert wurde. Meine Plattformdetails sind wie folgt:
Linux PG85213.egi.ericsson.com 3.5.0-030500-generisch # 201207211835 SMP Sat Jul 21 22:35:55 UTC 2012 x86_64 x86_64 x86_64 GNU / Linux
Java Version "1.7.0_45"
Java (TM) SE Laufzeitumgebung (Build 1.7.0_45-b18)
Java HotSpot (TM) 64-Bit Server-VM (Build 24.45-b08, gemischter Modus)
Ist das oben genannte Verhalten das gewünschte Verhalten von getThreadAllocatedBytes
?
Wenn dies der Fall ist, gibt es keine Möglichkeit, effektiven Speicher auf dem Heap zu finden, der von einem Thread verwendet wird.
Ich liste das komplette Programm als Referenz auf:
%Vor%Nach meinem Wissen gibt es keinen zuverlässigen Weg zur Laufzeit. Und wie in der Quellfrage angegeben, ist der Heap Eine gemeinsam genutzte Ressource und somit die Heap-Größe eines einzelnen Threads ist nicht sinnvoll, da sie sich mit den Objektreferenzen anderer Threads überschneidet.
Das heißt, wenn ich die "beibehaltene" Größe eines einzelnen Threads wissen möchte, und ja beibehaltene Größe ist eine andere, aber ähnliche Metrik zu der, die Sie gefragt haben, dann mache ich es, indem Sie einen Heap-Dump und dann mit MAT ( Ссылка ).
Ich kenne Leute, die Java-Agenten verwenden, um die Zuweisung von Objekten zu instrumentieren und dann zu verwenden eine schwache Referenz zu überwachen, wenn es GC'd wird. Der Leistungseinfluss ist jedoch hoch. Sehr hoch.
Sie können am besten mit einer Heuristik zur Laufzeit arbeiten und Unit-Tests, um sicherzustellen, dass der Speicher innerhalb der Grenzen bleibt . Sie können beispielsweise JMX verwenden, um die Heap-Größen zu überwachen, und wenn Sie feststellen, dass die alte Generation wächst, können Sie eine Warnung auslösen. Die Verwendung von getThreadAllocatedBytes zur Berechnung der Zuordnungsrate könnte ebenfalls nützlich sein.
Gute Laufzeitüberwachungstools: appdynamics , newrelic , VisualVM und yourkit
Für die Offline-Speicheranalyse mat und jclarity sind sehr gut.
Ein sehr nützliches Werkzeug, um zu erkennen, ob es ein Leck gibt oder das zumindest anders als erwartet verläuft, ist die Anzahl der Instanzen jeder Klasse, die sich derzeit auf dem Heap befinden, zu drucken: jcmd & lt; pid & gt; GC.class_histogram .
Java VisualVM kann verwendet werden, "um eine lokale Anwendung zu überwachen und real anzuzeigen Daten auf hoher Ebene über den Arbeitsspeicher-Heap, die Thread-Aktivität und die in der Java Virtual Machine (JVM) geladenen Klassen. Die Überwachung einer Anwendung verursacht geringen Overhead und kann für längere Zeiträume verwendet werden. "
Siehe auch Wie wird die Java-Speicherauslastung überwacht? für andere Möglichkeiten.
Tags und Links java memory multithreading memory-management