Verständnis Java-Heap-dump
Ich habe versucht zu finden ein memory leak in meine Anwendung für eine Woche jetzt ohne Erfolg. Ich habe versucht, einen heap-dump und verwenden Sie jhat Blick auf die dump-und trace-down-Speicher-Leck.
Ist dies eine beste Ansatz? Was ist der beste Weg, um track down der Speicherverlust mit der heap-dump.
Dankbar für Ihre Hilfe.
VM verwendet : java version "1.6.0_25"
Java(TM) SE Runtime Environment (build 1.6.0_25-b06)
Java HotSpot(TM) 64-Bit Server VM (build 20.0-b11, mixed mode)
JVM-Optionen : -Xmx1600m -XX:+UseParallelGC -XX:MaxPermSize=256m -Xms1600m -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -verbose:gc -Xloggc:/tmp/gc.melden Sie
OOME Stack trace: nicht bekommen Konnte. Der kernel getötet der Prozess mit out-of-memory-Fehler.
GC-Log : Die letzten paar Zeilen
48587.245: [GC [PSYoungGen: 407168K->37504K(476160K)] 506729K->137065K(1568448K), 3.0673560 secs] [Times: user=3.53 sys=0.00, real=3.07 secs]
50318.617: [GC [PSYoungGen: 444224K->37536K(476416K)] 543785K->175177K(1568704K), 3.6635990 secs] [Times: user=3.70 sys=0.00, real=3.67 secs]
50453.841: [GC [PSYoungGen: 70092K->2912K(476672K)] 207734K->178513K(1568960K), 1.0164250 secs] [Times: user=1.29 sys=0.00, real=1.02 secs]
50454.858: [Full GC (System) [PSYoungGen: 2912K->0K(476672K)] [PSOldGen: 175601K->137776K(1092288K)] 178513K->137776K(1568960K) [PSPermGen: 60627K->60627K(74368K)], 2.0082140 secs] [Times: user=2.09 sys=0.00, real=2.01 secs]
52186.496: [GC [PSYoungGen: 407104K->37312K(444416K)] 544880K->175088K(1536704K), 3.3705440 secs] [Times: user=3.93 sys=0.00, real=3.37 secs]
53919.975: [GC [PSYoungGen: 444416K->37536K(476608K)] 582192K->213032K(1568896K), 3.4242980 secs] [Times: user=4.09 sys=0.00, real=3.42 secs]
54056.872: [GC [PSYoungGen: 70113K->2880K(476480K)] 245609K->216320K(1568768K), 0.9691980 secs] [Times: user=1.19 sys=0.00, real=0.97 secs]
54057.842: [Full GC (System) [PSYoungGen: 2880K->0K(476480K)] [PSOldGen: 213440K->99561K(1092288K)] 216320K->99561K(1568768K) [PSPermGen: 60628K->60628K(72320K)], 2.2203320 secs] [Times: user=2.23 sys=0.01, real=2.22 secs]
55796.688: [GC [PSYoungGen: 406976K->37504K(476160K)] 506537K->137065K(1568448K), 3.2680080 secs]
Update: Auf die überprüfung der kernel-log-Meldungen, die eine oom-killer. Doch warum ist das system der Tötung der Prozess, ist es nicht, weil der Prozess frisst viele system-Ressourcen ( Arbeitsspeicher ).
Der link spricht abt native code, aber ich werde versuchen mithilfe von jconsole.
Haben Sie versucht, die Verwendung von "print Memory info" in den Verdacht, Teil des Codes? Es kann helfen
Java nicht mehr als die angegebene max-heap-Größe. Sie sollten die max-heap, was auch immer Ihre Anwendung erfordert und dann stellen Sie sicher, dass die server in Frage, das kann sehr viel Arbeitsspeicher auf dem java-Prozess. Ich fügte hinzu, mehr details unten.
InformationsquelleAutor Kathir | 2011-07-20
Du musst angemeldet sein, um einen Kommentar abzugeben.
Die Frage über die java-memory leaks ist ein Duplikat von diese, dass, etc. Noch, hier sind ein paar Gedanken:
Beginnen, indem er ein paar Haufen Schnappschüsse, wie beschrieben in der Antwort weiter oben verlinkt.
Dann, wenn Sie wissen, die ganze Anwendung ist gut, Sie können Augapfel die Instanz, die zählt, und herauszufinden, welcher Typ hat zu viele Instanzen kleben herum. Zum Beispiel, wenn Sie wissen, dass Sie eine Klasse ist ein singleton, aber Sie sehen 100 Instanzen dieser Klasse im Speicher, dann ist das ein Sicheres Zeichen dafür, dass etwas lustig ist, geht es. Alternativ können Sie auch vergleichen Sie die snapshots, um zu ermitteln, welche Arten von Objekten sind immer mehr im Laufe der Zeit; der Schlüssel hier ist, dass Sie suchen für relative Wachstum über einige Nutzungszeitraum.
Sobald Sie wissen, was ist undicht, Sie verfolgen zurück durch die Referenzen zu finden, die root-Referenz, die nicht abgeholt werden.
Schließlich erinnern, dass, es ist möglich, dass Sie einen OutOfMemoryError nicht weil Sie undicht Speicher, sondern weil Sie einen Teil Ihrer heap ist zu klein für die Anwendung. Um zu überprüfen, ob dies der Fall ist:
Update: ich bin mir nicht sicher, was "kernel getötet der Prozess mit out-of-memory-Fehler" in Ihrer neuesten update bedeutet, aber ich denke, man könnte sagen, dass die linux out-of-memory-killer aufgerufen wurde. War dies der Fall? Dieses problem ist völlig unabhängig von java OutOfMemoryError. Für mehr details über das, was passiert, werfen Sie einen Blick auf die links von der Seite, die ich gerade verlinkt sind, einschließlich diese und dass. Aber die Lösung zu deinem problem ist einfach: verwenden Sie weniger Speicher auf dem server in Frage. Ich nehme an, Sie könnten die Tropfen die min-und max-heap-size der java-Prozess in Frage, aber Sie müssen sicher sein, dass Sie nicht ausgelöst echten java-OutOfMemoryErrors. Können Sie verschieben Sie einige Prozesse, die an anderer Stelle? Können Sie setzen die memory-killer mit dem start-up für einen bestimmten Prozess?
Das Verständnis einer java-heap-dump ist anders als debugging-Fehler wegen ungenügenden Speicherplatzes. Ich werde aktualisieren, meine Antwort mit etwas mehr information über die später.
Auch, Sie habe noch nicht gesagt, was Sie gefunden haben, wenn Sie im Vergleich Instanz zählt. Habe jede Art von Objekt, das Wachstum in der Anzahl? Für was es Wert ist, verstehe ich nicht, welche Relevanz "die system-Prozess immer noch zeigt, dass der Speicher genutzt" hat, aber die java-Prozess darf nicht stoppen, wenn ein OOME passiert.
Die Instanz zählt, zeigten eine Menge HashMapEntry Instanzen. Ich glaube diese Einträge sind von Hibernate und wir Holen eine Menge von Datenbank-Datensätzen. Aber irgendwann bekommen Sie alle gc ' ed.
Ist Hibernate-caching-Daten? Wenn Sie vergleichen mehrere heap-dumps, bedeutet dies, cache-Größe im Laufe der Zeit wachsen? Woher wissen Sie, dass Daten aus dem cache verdrängten -- z.B. gibt es eine max Größe, funktioniert die cache-Verwendung schwacher Referenzen, etc? Auch, wenn Sie laden eine Menge von Daten, dann haben Sie vielleicht haben deine max-heap-Größe zu niedrig ist.
InformationsquelleAutor jtoberon
Speicher-Lecks behoben werden können, indem Sie die folgenden unten genannten 3 einfachen Schritten:
Schritt 1: Erfassen heap-dump, die während der frühen Phase
Starten Sie Ihre Anwendung. Lassen Sie es wirklichen Verkehr für 10 Minuten. An dieser Stelle erfassen heap-dump. Heap-Dump ist im Grunde snapshot-Speicher. Es enthält alle Objekte, die Ihren Wohnsitz in dem Speicher gespeicherten Werte in den Objekten, inbound & outbound Referenzen von diesen Objekt. Sie können erfassen Heap-dump erfasst werden können mit dem folgenden Befehl:
Wenn Sie nicht möchten, zu verwenden, jmap für die Erfassung von heap-dumps sind, sind hier einige andere Optionen, um erfassen heap-dumps.
Schritt 2: Erfassen heap-dump, bevor die Anwendung stürzt
Nach Schritt #1, die Anwendung ausführen lassen. Vor dem Absturz der Anwendung nehmen Sie eine andere heap-dump wieder. Oft ist es möglicherweise schwierig sein, zu erfassen heap-dumps, bevor es stürzt ab, weil wir nicht wissen, wenn Anwendung abstürzt. Ist es nach 30 Minuten, 3 Stunden, 3 Tage? Also, es ist ideal, um starten Sie Ihre Anwendung mit folgenden JVM-Eigenschaft:
Diese Eigenschaft wird ausgelöst, heap-dump-Recht bei der Anwendung Erfahrungen OutOfMemoryError.
Schritt 3: Analysieren heap-dumps
Objekte, die verursachen Speicherverluste wachsen über die Zeit. Wenn Sie die Objekte erkennen, deren Größe sich zwischen die heap-dumps erfasst in Schritt 1 und Schritt 2, dann sind die Objekte, die verursacht Speicherverlust.
Kann man sich überlegen, heap-dump-analyzer-tool wie HeapHero.io , Eclipse MAT für diesen Zweck. Wenn Sie laden Sie die heap-dumps zu einem Werkzeug, es wird ein Abschnitt reporting größten Objekte im Speicher. Vergleichen Sie in diesem Abschnitt zwischen heap-dump erfasst in Schritt #1 und Punkt #2. Wenn Sie bemerken, abnorme Wachstum von Objekten, dann sind Sie die diejenigen, die verursacht Speicherverlust in der Anwendung.
InformationsquelleAutor Ram Lakshmanan
Ich empfehlen, dass Sie überprüfen, meinen ursprünglichen Artikel zu diesem Thema. Java-heap-dump-Analyse kann Komplex sein, aber mit tools wie Eclipse Memory Analyzer vereinfacht den Prozess.
JVM-Heap-Dump sind nützlich für die folgenden Szenarien:
Referenz: Java-heap-dump: sind Sie bis zur Aufgabe?
InformationsquelleAutor P-H