System.gc () vs GC-Schaltfläche in JVisualVM / JConsole

Ich teste derzeit meinen Proof-of-Concept-Prototyp für XML-Schemata und baue auf einer sehr speicherintensiven externen Bibliothek für Baumautomaten auf (für die ich die Quellen habe). Ich möchte "echte Spitze" (Haufen) zeichnen ) Speicherverbrauch der verschiedenen Läufe mit zunehmender Schemagröße (die verwendete Metrik passt zu meinem Zweck und hat keinen Einfluss auf die Frage) oder zumindest eine vernünftige Annäherung daran.

Um eine Größenordnung anzugeben, für einen Lauf mit einer realen Spitze von 100 MB (ich habe getestet, dass er mehrmals genau dieselbe Konfiguration von Eingaben / Parametern ausführt und den JVM-Speicher mit -Xmx und -Xms zwingt, den Wert zu verringern), erhalte ichAusnahme im Thread "main" java.lang.OutOfMemoryError: GC-Overhead-Limit überschritten <100MB, mit stabilen und wiederholbaren Ergebnissen) belegen ungefähr 1,1 GB, deshalb ist es für mich extrem wichtig, die tatsächliche Anzahl zu ermitteln, da sie sehr unterschiedlich sind!

Ich habe die letzten 10 Tage damit verbracht, Fragen im Web und im Stackoverflow zu lesen. Was ich eigentlich weiß, ist:

System.gc () "schlägt" einen GC-Lauf vor, erzwingt ihn in keiner Weise, sodass es nicht möglich ist, Speicherauslastungsspitzen zu erkennen

Was normalerweise vorgeschlagen wird, ist, die Objektbesetzung zu zählen (ich habe gesehen)Größe von Für dieses Projekt habe ich versucht, und es funktioniert einwandfrei, auch wenn es nicht meinen Anforderungen entspricht. Dies ist für mich nicht realisierbar, da eine starke Speicherzuweisung aufgrund der Erstellung einer großen Anzahl von Sammlungsiteratoren (Set, List und Map) in unterschiedlichen Iteratoren erfolgt Methoden, die sehr oft aufgerufen werden (sagen wir Millionen für einen Durchlauf von 10 Minuten für das, woran ich mich erinnere), so dass es extrem schwierig wäre, alle beteiligten Objekte zu erkennen und die Summen auszuführen (ich habe viele, viele Durchläufe in Tagen mit debuggt) Speicherverbrauchsdiagramme, ohne nur einen Flaschenhals identifizieren zu können)

Es gibt keine einfache Möglichkeit, die Speicherbelegung einer Methode (ausgedrückt als die Spitze der Objektspeicherzuordnung) zu ermitteln.

Tatsache ist, dass ich selbst erfahren habe, dass System.gc () -Aufrufe nicht zuverlässig sind (z. B. unterschiedliche Ausführungen derselben Konfiguration, unterschiedlicher Speicher, der nach einem System.gc () gelesen wird, weil der GC tatsächlich aufgerufen wird oder nicht), aber wann Ich drücke die "GC-Taste" in JVisualVM oder Jconsolenoch nie GC wird nicht ausgeführt oder weigert sich, dies zu tun.

Meine Frage lautet also: Aufruf der Implementierung dieses Buttons (ich habe es noch nicht ausprobiert, aber für das, was ich bisher gelesen habe, scheint es mit jconsole.jar machbar zu seinApi anhängen) unterscheidet sich vom direkten Aufruf von System.gc () von meinem Code und löst so mein Problem? Wenn nicht, wie erklären Sie das "deterministische Verhalten" dieser Schaltfläche?

Bisher habe ich einige manuelle Tests des realen Speicherpeaks bei 10 zunehmenden Schemagrößen durchgeführt (für diese Art der Messung werden die Schemata automatisch aus einem einzelnen "Komplexitätsparameter" generiert) und die erwartete Kurve aufgezeichnet, wenn ich dies nicht kann Eine bessere Lösung erhalten Ich möchte meinen Code als externe JAR-Datei mit -Xmx / -Xms ausführen, die geringfügig unter meiner Prognose des erwarteten Speicherpeaks liegt. Dabei wird die OutMemoryException im externen Prozess ErrorStream abgefangen und mit erhöhtem Speicher neu gestartet, bis ein vollständiger Lauf ausgeführt ist erreicht. (Wenn die Vorhersage des naiven Gedächtnisses nicht robust genug ist, werde ich geeignete Techniken des maschinellen Lernens anwenden). Ich weiß, dass dies keine elegante Lösung ist, aber in meinem Szenario (Wissenschaft) kann ich es mir leisten, zusätzliche Zeit für diese Messungen aufzuwenden. Wenn Sie weitere Vorschläge oder Verbesserungen zu dieser Bruteforce-Methode haben, können Sie diese gerne (extrem) teilen.

Systeminfo (Maschine ist ein Fedora 17, 64 Bit):

Java-Version "1.7.0_04" Java (TM) SE-Laufzeitumgebung (Build 1.7.0_04-b20) Java HotSpot (TM) 64-Bit-Server-VM (Build 23.0-b21, gemischter Modus)

Danke im Voraus, Alessandro

Antworten auf die Frage(4)

Ihre Antwort auf die Frage