2016-06-01 7 views
1

Ich entwickle eine Desktop-Java-Anwendung und versuche, die Speichernutzung zur Laufzeit mit Java Visual VM zu optimieren.Java-Heap-Wachstum

Die Sache ist, dass ich bemerkt habe, dass mein benutzter Haufen um 1mb/s wächst und ich versuche herauszufinden, was das verursacht. Dies ist, wie es aussieht:

enter image description here

Zunächst einmal habe ich bemerkt, dass die JVM scheint zur Laufzeit von selbst ziemlich viel Speicher zu zuweisen. Ich habe versucht, ein Dummy-Programm zu machen, das gerade schläft und die Zunahme des benutzten Heaps schien ungefähr 0.2Mb/s zu sein.

Allerdings weist meine Anwendung offensichtlich mehr zu. Und ich weiß, dass ich zur Laufzeit ziemlich viele Objekte erzeuge, aber es sollte nicht in der Nähe von MBs/s sein, eher wie Bytes/Sekunde.

Also habe ich ein paar Dumps gemacht und sie verglichen. Hier ist der erste, wenn ein frischer GC aufgerufen wurde:

enter image description here

Und hier ist die andere, wo der verwendete Haufen gewachsen ist ~ 100 MB:

enter image description here

Hier ist der Vergleich:

enter image description here

Nun, was mich verwirrt ist, dass ich nicht finden kann y Spur der zusätzlichen 100 mb in den beiden Deponien.

Gesamt-Bytes sind gleich. Klassen sind gleich. Instanzen sind ungefähr gleich. Und der Vergleich gibt mir keine Hinweise. Die Dumps bestätigen jedoch, dass ich nur eine Handvoll Klassen/s verteile. Also was gibt es?

Update 1: Die Eclipse-Speicher-Manager:

enter image description here

(Die Verdächtigen sind nicht Täter). Und ich möchte betonen, dass visualVM mir zum Zeitpunkt der Dumps einen Unterschied von 100MB im verwendeten Heap zeigte. Meine In-Anwendung

print("Used Mbs: " + (r.totalMemory() - r.freeMemory())/mb); 

Auch dies bestätigt. ('r' ist eine Runtime-Instanz)

+0

könnten Sie uns Code zeigen? – niceman

+1

Können Sie nach "nicht referenzierten" Objekten im Heap-Dump suchen? Die Objekte können zwar zugeordnet, aber nicht referenziert und für GC reserviert sein. – Konrad

+0

Konrad, ich kann anscheinend nicht herausfinden, wie man das mit Java visualVM macht. Wissen Sie? – Jake

Antwort

2

Ich glaube nicht, dass Sie ein Problem haben.

Sie müssen etwas über das JVM-Speichermodell und die Generationen erfahren.

Das Sägezahnmuster für junge Generation sagt so. Das ist der Müllsammler, der seine Arbeit macht.

Das permanente Zeugs, das wächst, ist Perm gen (oder es war für JDK 7 und früher). Dort leben Strings, .Class-Byte-Code usw.

+0

Das ist die Antwort, auf die ich hoffe ist JVM verwandt und nicht wegen der beschissenen Codierung? – Jake

+0

Ich habe Ihren Code oder den einer der Bibliotheken, die Sie verwenden, nicht gesehen, daher kann ich die Qualität nicht kommentieren. (Ich wette, die Moderatoren würden es wünschen.) ein anderes Adjekt gewählt ive.) Ich kann sagen, dass Ihr einfacher Testfall nicht gut ist, um Speicherleckprobleme zu lösen. Besser ist es, echten Code zu verwenden und ihn Lasten zu unterwerfen, die über einen langen Zeitraum hinweg Ihre wirklichen Anwendungsfälle darstellen. Das ist, wo Speicherlecks ein Problem sein werden. Wie groß sind die JARs, die geladen werden? Diese .class-Datei-Bytes müssen an einen anderen Ort gehen, wenn sie geladen sind. – duffymo

+0

Aber würden Sie zustimmen, dass die Ergebnisse meines einfachen Tests seltsam sind? – Jake

0

Ich fand diese nette Funktion in visualVM - Überwachung.

Also, ich habe das schon Überwachung:

public static void main(String[] args) { 

    while (true){ 
     try { 
      Thread.sleep(10); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 


} 

Und es scheint, dass die JVM Lasten von Zeichen zuteilt [], Object [], byte [], int [], TreeMap $ Eintrag und eine solche. Ich habe meine Anwendung ebenfalls beobachtet und es scheint dem gleichen Muster zu folgen, nur größere Mengen davon. Also werde ich das als Schuld aller Orakel ausschließen. Der JVM-Overhead wächst mit der Anwendung mit. Es sei denn, jemand kann sich eine bessere Idee einfallen lassen?