Wie funktioniert das Speicherprofil in Java?
Ich bin immer noch lernen, die Seile von Java also sorry, wenn es eine offensichtliche Antwort auf diese Frage. Ich habe ein Programm, das unter eine Tonne von Speicher, und ich will einen Weg zur Reduzierung seiner Verwendung, aber nach der Lektüre SO viele Fragen, die ich habe die Idee, dass ich brauche, um zu beweisen, wo das problem ist, bevor ich anfange zu optimieren.
So, hier ist was ich getan habe, ich habe einen break-Punkt an den Anfang von meinem Programm und es lief, dann habe ich angefangen visualVM und hatte es Profil den Speicher(ich habe auch die gleiche Sache in netbeans einfach, die Ergebnisse zu vergleichen, und Sie sind die gleichen). Mein problem ist, ich weiß nicht, wie Sie zu Lesen, ich habe die höchste Gegend nur sagen: char[]
und ich sehe keinen code oder alles(was Sinn macht, weil visualvm ist die Verbindung zu der jvm und kann nicht sehen, meine Quelle, aber netbeans auch nicht zeigen Sie mir die Quelle, wie es funktioniert, wenn dabei die cpu-profiling).
Im Grunde, was ich wissen möchte ist, welche variable(und hoffentlich mehr details wie in die Methode) der gesamte Speicher genutzt wird, so kann ich den Fokus auf die Arbeit dort. Gibt es eine einfache Möglichkeit, dies zu tun? Ich Moment arbeite ich mit eclipse und java zu entwickeln(und installiert visualVM-und netbeans-speziell für profiling, bin aber bereit zu installieren irgendetwas anderes, dass Sie das Gefühl bekommt, diesen job zu erledigen).
EDIT: im Idealfall, ich bin auf der Suche nach etwas, dass alle meine Objekte und Sortieren Sie diese nach Größe(so kann ich sehen, welcher Beschlag-Speicher). Derzeit gibt es Allgemeine Informationen wie string[] oder ein int[] aber ich möchte wissen, welches Objekt seiner beziehe, so kann ich immer auf seine Größe weiter optimiert.
InformationsquelleAutor der Frage Error_404 | 2012-04-11
Du musst angemeldet sein, um einen Kommentar abzugeben.
Strings sind problematisch
Grundsätzlich in Java
String
Referenzen ( Dinge, dass die Nutzungchar[]
hinter den kulissen ) Dominieren die meisten business Anwendungen Speicher weisen. Wie Sie entstehen, bestimmt, wie viel Speicher Sie verbrauchen in der JVM.Gerade weil Sie so grundlegend für die meisten business-Anwendungen als Daten-Typ, und Sie sind eines der speicherfressensten als gut. Dies ist nicht nur eine Java-Sache,
String
Daten-Typen nehmen viel Speicher in so ziemlich jeder Sprache und run-time library, weil zumindest Sie sind einfach arrays von 1 byte pro Zeichen oder zu den schlechteren ( Unicode ) Sie sind arrays mit mehreren bytes pro Zeichen.Einmal beim profiling CPU-Auslastung auf eine web-app, die hatte auch eine Oracle-JDBC-Abhängigkeit habe ich entdeckt, dass
StringBuffer.append()
dominiert die CPU-Zyklen um viele Größenordnungen über alle anderen Methodenaufrufe kombiniertviel weniger irgendeine andere einzelne Methode aufrufen. Der JDBC-Treiber hat vieleString
manipulation, Art der trade-off mitPreparedStatements
für alles.Was Sie besorgt sind, können Sie nicht kontrollieren, nicht direkt jedenfalls
Was Sie sich konzentrieren sollten, was ist in Ihrer Kontrolle, die sicherstellen, dass Sie don ' T halten, um Referenzen mehr, als Sie brauchen, und dass Sie nicht duplizieren, die Dinge unnötig. Die garbage-collection-Routinen in Java sind stark optimiert, und wenn Sie lernen, wie Ihre algorithmen funktionieren, können Sie sicherstellen, dass Ihr Programm verhält sich in der optimale Weg für diejenigen, die algorithmen zu arbeiten.
Java-Heap-Speicher ist nicht wie bei manuell verwalteten Speicher in den anderen Sprachen, die diese Regeln nicht gelten
Als was gelten Speicherverluste in anderen Sprachen sind nicht die gleiche Sache/Ursache wie in Java mit garbage collection system.
Wahrscheinlich im Java-Speicher nicht verbraucht ist, durch ein einziges uber-Objekt, das undicht ist ( dangling reference in anderen Umgebungen ).
Ist es wahrscheinlich viel kleiner Zuweisungen weil
StringBuffer
/StringBuilder
Objekte nicht angemessen proportioniert auf den ersten instantantations und müssen dann automatisch wachsen diechar[]
arrays zu halten anschließendeappend()
Anrufe.Diese temporäre Objekte gehalten werden können, um länger als erwartet, bis der garbage collector, weil der Umfang und die vielen anderen Dinge, die können variieren zur Laufzeit.
BEISPIEL: der garbage collector kann entscheiden, es gibt Kandidaten, sondern weil er der Auffassung ist, dass es viel Speicher noch zu haben, es könnte zu teuer sein, Zeit klug, Spülen Sie Sie aus, an diesem Punkt in der Zeit, und es wird gewartet, bis der Speicher Druck wird höher.
Der garbage collector ist jetzt wirklich gut, aber es ist keine Zauberei, wenn Sie dabei sind, Entartete Dinge, es wird es nicht optimal funktionieren. Es gibt sehr viel Dokumentation im internet über den garbage collector-Einstellungen für alle Versionen des JVMs.
Diese un-referenzierte Objekte können nur noch nicht erreicht, die Zeit, die der garbage collector denkt, es braucht Sie, um für Sie zu sein gelöscht aus der Erinnerung, oder es könnte sein, Verweise auf Ihnen gehalten durch ein anderes Objekt (
List
) zum Beispiel, dass Sie nicht erkennen, noch Punkte auf das Objekt. Dies ist, was die meisten gemeinhin als ein Leck in Java, das ist ein Verweis Speicherverlust genauer.BEISPIEL: Wenn Sie wissen, dass Sie brauchen, um zu bauen einen 4K -
String
mit einemStringBuilder
schaffen es mitnew StringBuilder(4096);
nicht der Standard, das ist wie 32 und wird sofort beginnen erstellen von Müll, der darstellen kann, viele Male, was Sie denken, das Ziel sollte sein, die kluge Größe.Können Sie entdecken, wie viele, welche Arten von Objekten, die instanziiert sind mit VisualVM, dies wird Ihnen sagen, was Sie wissen müssen. Es gibt nicht eine große blinkende Licht, dass die Punkte an eine einzelne Instanz einer einzigen Klasse, die sagt, "Dies ist der große Gedächtnis der Verbraucher!", es sei denn, es ist nur eine Instanz von einige
char[]
Sie Lesen einige riesige Datei in, und dies ist nicht möglich, da viele andere Klassen verwendenchar[]
intern; und dann haben Sie ziemlich viel wusste, dass bereits.Ich don ' T sehen jede Erwähnung von
OutOfMemoryError
Werden Sie wahrscheinlich nicht haben ein problem in Ihrem code, garbage collection-Systems, nur vielleicht nicht immer unter genügend Druck, um kick und freigeben von Objekten, die Sie denke sollte es Aufräumen. Was Sie denken, ist ein problem, wahrscheinlich nicht, nicht, es sei denn, dein Programm stürzt mit
OutOfMemoryError
. Das ist nicht C, C++, Objective-C, oder jede andere manuelle Speicherverwaltung Sprache /runtime. Sie nicht bekommen, zu entscheiden, was im Speicher ist oder nicht auf der detail-Ebene, die Sie erwarten, sollten Sie in der Lage sein.InformationsquelleAutor der Antwort feeling unwelcome
In JProfilerkönnen Sie gehen, um die heap walker und aktivieren Sie die größten Objekte-Ansicht. Sehen Sie die Objekte, die behalten die meisten Speicher. "Beibehalten" Speicher ist der Speicher, der wäre vom garbage collector freigegeben, wenn Sie entfernt das Objekt.
Können Sie dann öffnen Sie den Objekt-Knoten finden Sie in der Referenz-Baum der Objekte beibehalten. Hier ist ein Screenshot der größten Objekt-Ansicht:
Disclaimer: Meine Firma entwickelt JProfiler
InformationsquelleAutor der Antwort Ingo Kegel
Ich würde empfehlen, das erfassen von heap-dumps und mit einem tool wie Eclipse MAT , analysieren Sie Sie. Es gibt viele tutorials zur Verfügung. Es bietet einen Blick auf die dominator-Baum Einblicke in die Beziehungen zwischen den Objekten auf dem heap. Speziell für das, was Sie erwähnt, "der Weg zum GC-Wurzeln" - Funktion der MATTE wird Ihnen sagen, wo die Mehrheit derjenigen, char[], String[] und int [] - Objekte Bezug genommen wird. JVisualVM kann auch nützlich sein bei der Identifizierung von Leckagen und Zuwendungen, insbesondere durch die Verwendung von snapshots mit allocation stack traces. Es gibt durchaus ein paar walk-throughs des Prozesses immer die snapshots und vergleichen, finden Sie die Zuordnung Punkt.
InformationsquelleAutor der Antwort Rob Tanzola
Java JDK kommt mit JVisualVM unter bin-Ordner, wenn Sie Ihre Anwendungs-server (zum Beispiel), die Sie ausführen können, visualvm und schließen Sie es an den localhost, die Ihnen die Speicherreservierung und ermöglichen Ihnen das ausführen heap-dump -
Weitere detaillierte Schritte auf, wie zu aktivieren:
http://sysdotoutdotprint.com/technologies/java/6
InformationsquelleAutor der Antwort mel3kings
Wenn Sie visualVM, um überprüfen Sie Ihre Speichernutzung konzentriert Sie sich auf die Daten, nicht die Methoden. Vielleicht Ihre große char[] Daten, die durch viele String-Werte? Es sei denn, Sie sind mit Rekursion, die Daten werden nicht von lokalen Variablen. So können Sie den Fokus auf die Methoden, die das einfügen von Elementen in großen Datenstrukturen. Um herauszufinden, was genaue Aussagen dazu, Ihren "Speicher-Leck", schlage ich vor, Sie zusätzlich
InformationsquelleAutor der Antwort DaveFar