Frage

Was ist der beste Weg, um Debug-java.lang.OutOfMemoryError Ausnahmen?

Wenn dies auf unsere Anwendung geschieht, unser App-Server (Weblogic) eine Heap Dump-Datei. Sollten wir die Heap Dump-Datei verwenden? Sollten wir einen Java-Thread-Dump erzeugen? Was genau ist der Unterschied?


Update: Was ist der beste Weg, Thread-Dumps zu generieren? Ist kill -3 (unsere App läuft auf Solaris) die beste Möglichkeit, die App und erzeugt ein Thread-Dump zu töten? Gibt es einen Weg, um das Thread-Dump zu erzeugen, aber nicht tötet die App?

War es hilfreich?

Lösung

Analyse und Festlegung Out-of-Memory-Fehler in Java ist sehr einfach.

In Java Objekte, die Speicher belegen sind alle mit einigen anderen Objekten verknüpft, einen riesigen Baum zu bilden. Die Idee ist, die größten Zweige des Baumes zu finden, die in der Regel zu einem Speicherverlust Situation (in Java zeigen werden, lecken Sie Speicher nicht, wenn Sie vergessen, ein Objekt zu löschen, aber wenn Sie vergessen, das Objekt zu vergessen, dh Sie halten Verweis auf sie irgendwo).

Schritt 1. Aktivieren Sie Heap während der Laufzeit-Dumps

Führen Sie Ihren Prozess mit -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp

(Es ist sicher, diese Optionen haben immer aktiviert. Den Pfad einstellen je nach Bedarf, muss sie durch den Java-Benutzer beschreibbar sein)

Schritt 2. Reproduzieren der Fehler

Lassen Sie die Anwendung laufen, bis der OutOfMemoryError auftritt.

Die JVM wird automatisch eine Datei wie java_pid12345.hprof schreiben.

Schritt 3. Der Dump Fetch

Kopieren java_pid12345.hprof auf Ihren PC (es mindestens so groß wie Ihre maximale Heap-Größe sein, so kann sehr groß werden - gzip es, falls erforderlich)

.

Schritt 4. Öffnen Sie die Dump-Datei mit IBMs Heap Analyzer oder Eclipse Memory Analyzer

Der Heap-Analyzer wird Sie mit einem Baum aller Objekte präsentiert, die zum Zeitpunkt des Fehlers noch am Leben waren. Die Chancen stehen gut es zeigen Sie auf direkt auf das Problem, wenn es geöffnet wird.

Hinweis: geben HeapAnalyzer genug Speicher, da es Ihre gesamte Dump laden muss

java -Xmx10g -jar ha456.jar

Schritt 5. Bereiche der größten Haufen Verwendung identifizieren

Durchsuchen durch den Baum von Objekten und Objekte identifiziert, die sich um unnötig gehalten werden.

Hinweis kann auch das passieren alle der Objekte notwendig sind, was bedeuten würde Sie einen größeren Haufen benötigen. Größe und Melodie der Halde entsprechend .

Schritt 6. Fix Code

Achten Sie darauf, nur Halten Sie Gegenstände um, dass Sie tatsächlich benötigen. Entfernen Sie Gegenstände aus Sammlungen in angemessener Zeit. Achten Sie darauf, keine Verweise auf Objekte zu halten, die nicht mehr benötigt werden, nur dann können sie sein Garbage Collection.

Andere Tipps

Ich habe Erfolg hatte eine Kombination der Verwendung von Eclipse-Memory Analyzer (MAT) und Java VM von Visual Heapspeicherauszüge zu analysieren. MAT hat einige Berichte, dass Sie ausführen können, dass Sie eine allgemeine Vorstellung davon, wo Ihre Bemühungen innerhalb des Codes zu konzentrieren. VisualVM hat eine bessere Schnittstelle (meiner Meinung nach) für tatsächlich den Inhalt der verschiedenen Objekte inspizieren, dass Sie bei der Prüfung interessiert sind. Es verfügt über einen Filter, wo Sie können es alle Instanzen einer bestimmten Klasse zeigen und sehen, wo sie verwiesen wird und was sie selbst verweisen. Es ist schon eine Weile her, seit ich entweder Werkzeug dafür verwendet haben, können sie nun genauer Funktionen durchgeführt werden. Zu der Zeit für mich, beide unter Verwendung funktionierten gut.

Es ist in der Regel sehr schwierig zu debuggen OutOfMemoryError Problemen. Ich würde empfehlen, ein Profilierungswerkzeug. JProfiler funktioniert ziemlich gut. Ich habe es in der Vergangenheit verwendet, und es kann sehr hilfreich sein, aber ich bin sicher, es gibt andere, die mindestens so gut sind.

Ihre spezifische Fragen beantworten:

Ein Heap Dump ist eine vollständige Sicht auf den gesamten Haufen, das heißt alle Objekte, die mit new erstellt wurden. Wenn Sie mit der Erinnerung heraus, dann wird dies ziemlich groß sein. Es zeigt Ihnen, wie viele von jeder Art von Objekt, das Sie haben.

Ein Thread-Dump zeigt Ihnen die Stapel für jeden Thread, zeigt Ihnen, wo in dem Code jeder Thread zum Zeitpunkt des Dumps ist. Beachten Sie, dass jeder Thread die JVM verursacht haben könnte Speicher laufen, aber es könnte ein anderer Thread sein, dass tatsächlich die Fehler auslöst. Beispielsweise Thread 1 reserviert einen Byte-Array, dass auffüllt alle verfügbaren Heap-Speicher, dann 2 versucht Gewinde ein 1-Byte-Array zuzuteilen und wirft einen Fehler.

Sie können auch verwenden jmap / jhat zu einem laufenden Java-Prozess zu befestigen. Diese (Familie) Tools sind wirklich nützlich, wenn Sie eine Live laufende Anwendung zu debuggen haben.

Sie können auch als Crontask Protokollierung in eine Datei verlassen jmap laufen, die Sie später analysieren können (es ist etwas, was wir nützlich gefunden haben, ein Live-Speicherleck zu debuggen)

jmap -histo:live <pid> | head -n <top N things to look for> > <output.log>

jmap kann auch einen Heap Dump zu erzeugen, mit der -dump Option verwendet werden, die durch die jhat gelesen werden kann.

Sehen Sie den folgenden Link, um weitere Informationen zu http: //www.lshift .net / blog / 2006/03/08 / java-Speicher-Profilieren-mit-jmap-and-jhat

Dies ist ein weiterer Link zu Lesezeichen http://java.sun.com/developer/technicalArticles/J2SE/monitoring/

Was ist der beste Weg, um Debug-java.lang.OutOfMemoryError Ausnahmen?

Der OutOfMemoryError beschreibt Art von Fehlern in der Nachrichtenbeschreibung. Sie haben die Beschreibung der Fehlermeldung zu überprüfen, um die Ausnahme zu behandeln.

Es gibt verschiedene Ursachen für nicht genügend Arbeitsspeicher Ausnahmen. Siehe Oracle-Dokumentation für weitere Details .

java.lang.OutOfMemoryError: Java heap space:

Ursache . Das detaillierte Meldung Java Heap-Speicher zeigt Objekt nicht in dem Java-Heap zugeordnet werden kann

java.lang.OutOfMemoryError: GC Overhead limit exceeded:

Ursache: Die detaillierte Meldung „GC Obergrenze überschritten“ zeigt an, dass der Garbage Collector die ganze Zeit läuft und Java-Programm schreitet sehr langsam voran

java.lang.OutOfMemoryError: Requested array size exceeds VM limit:

Ursache : Die detaillierte Meldung „Requested Feldgrße überschreitet VM limit“ zeigt an, dass die Anwendung (oder von dieser Anwendung verwendet, APIs) versucht, ein Array zuzuweisen, die größer als die Speichergröße beträgt

java.lang.OutOfMemoryError: Metaspace:

Ursache: Java-Klasse Metadaten (die virtuellen Maschinen interne Darstellung der Java-Klasse) im nativen Speicher zugewiesen (hier bezeichnet als mLokal)

java.lang.OutOfMemoryError: request size bytes for reason. Out of swap space?:

Ursache: Die Detail Nachricht "Anfrage Größe Bytes für Vernunft aus Swap-Bereich.?" erscheint eine OutOfMemoryError Ausnahme. Allerdings meldet die Java HotSpot VM Code, um diese scheinbare Ausnahme, wenn eine Zuweisung aus dem nativen Haufen gescheitert und die einheimischen Haufen möglicherweise nahe an Erschöpfung

java.lang.OutOfMemoryError: Compressed class space

Ursache: Auf 64-Bit-Plattformen ein Zeiger auf Klasse Metadaten kann durch einen 32-Bit (mit UseCompressedOops) versetzt dargestellt werden. Dies wird durch die Befehlszeilenparameter UseCompressedClassPointers (standardmäßig) gesteuert.

Wenn der UseCompressedClassPointers verwendet wird, wird die Menge an Speicherplatz zur Verfügung für die Klasse Metadaten in Höhe CompressedClassSpaceSize fixiert. Wenn der Raum für UseCompressedClassPointers benötigt CompressedClassSpaceSize überschreitet, wird ein java.lang.OutOfMemoryError mit Detail Druck Klasse Raum geworfen wird.

Hinweis: Es gibt mehr als eine Art von Klasse Metadaten - klass Metadaten und anderen Metadaten. Nur klass Metadaten in dem Raum gespeichert durch CompressedClassSpaceSize begrenzt. Die anderen Metadaten in metaSpace gespeichert.

Sollten verwenden wir die Heap Dump-Datei? Sollten wir einen Java-Thread-Dump erzeugen? Was genau ist der Unterschied?

Ja. Sie können diesen Haufen Heap Dump-Datei verwenden, um das Problem mit Profilierungs Tools wie VisualVM oder mat Sie können Thread-Dump erhalten einen weiteren Einblick über den Status der Threads verwenden.

Siehe diese SE Frage der differenes wissen:

Unterschied zwischen Javacore, Thread-Dump und Heapdump in Websphere

Was ist der beste Weg, Thread-Dumps zu generieren? Ist Kill -3 (unsere App läuft auf Solaris) die beste Möglichkeit, die App und erzeugt ein Thread-Dump zu töten? Gibt es einen Weg, um das Thread-Dump zu erzeugen, aber die App nicht töten?

kill -3 <process_id> erzeugt Thread-Dump und dieser Befehl nicht tötet Java-Prozess.

Es sieht aus wie IBM, ein Werkzeug für die Analyse dieser Heapspeicherauszüge bietet: http: //www.alphaworks .ibm.com / tech / heaproots ; mehr unter http://www-01.ibm.com/support/docview .wss? uid = swg21190476 .

Wenn Sie ein Werkzeug, um Blick auf der Heapdump, Blick auf jedem Thread erhalten, die in dem Laufzustand in dem Thread-Stack war. Es ist wahrscheinlich einer von denen, die den Fehler bekam. Manchmal ist der Heapdump werden Ihnen sagen, welche Gewinde an der Spitze den Fehler Recht hat.

Das sollten Sie in die richtige Richtung weisen. verwendet dann Standard-Debugging-Techniken (Logging, Debugger, etc.) zu feilen in dem Problem. Verwenden Sie die Runtime-Klasse die aktuelle Speichernutzung zu erhalten und melden Sie es als Verfahren oder Verfahren in Frage ausgeführt wird.

Ich benutze Eclipse-Memory Analyzer im Allgemeinen. Es zeigt die mutmaßlichen Täter (die Objekte, die die größten Teil der Heapdump besetzen) und verschiedene Anruf Hierarchien, die diese Objekte erzeugt. Sobald das Mapping ist dort können wir auf den Code gehen Sie zurück und versuchen zu verstehen, ob es ein möglicher Speicher ist Leck irgendwo in dem Codepfad.

Allerdings OOM bedeutet nicht immer, dass es ein Speicherverlust. Es ist immer möglich, dass der Speicher durch eine Anwendung während des stabilen Zustandes oder unter Last benötigt wird, ist in der Hardware / VM nicht zur Verfügung. Zum Beispiel gibt es einen 32-Bit-Java-Prozess sein könnte (Max-Speicher verwendet ~ 4 GB), wo als die VM nur 3 GB. In einem solchen Fall zunächst kann die Anwendung laufen gut, aber OOM angetroffen werden können, wie und wann der Speicherbedarf nähert sich 3GB.

Wie bereits von anderen erwähnt, Dump festzuhalten Faden ist nicht teuer, aber die Erfassung Heapdump ist. Ich habe beobachtet, dass während Heapdump Anwendung (in der Regel) friert die Erfassung und nur ein Kill gefolgt von Neustart wiederherstellen hilft.

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