2010-02-26 3 views
38

Wir erstellen mehrere untergeordnete Klassenladeprogramme, die in mehrere Subanwendungen in einen Java-Anwendungscontainer geladen werden können. Wenn sich der Klassenpfad eines bestimmten Klassenladeprogramms geändert hat (d. H., Dass Gefäße hinzugefügt, gelöscht, aktualisiert wurden), wird der alte Klassenladeprogramm weggeworfen (nicht referenziert) und ein neuer Klassenladeprogramm für den neuen Klassenpfad von Gefäßen erstellt.Wann und wie ist ein Java Classloader für die Garbage Collection markiert?

Nachdem der Klassenpfad aktualisiert und die Hot-Bereitstellung ausgelöst wurde, wurde ein Heap-Dump ausgeführt. Der Heapspeicherauszug (mit Memory Analyzer) zeigt an, dass die alten Klassenladeprogramme nicht als Garbage Collected erfasst wurden. Bestimmte Klassen im übergeordneten Klassenlader speicherten die alten Klassenlader. Die folgenden Dinge wurden aufgerufen, diese Caches zu löschen:

java.lang.ResourceBundle.clearCache(classLoader); 
org.apache.commons.logging.LogFactory.release(classLoader); 
java.beans.Introspector.flushCaches(); 

Auch nach dem oben genannten Caches zu leeren, wurden die alten Klassenlader noch nicht Müll gesammelt werden. Die verbleibenden Verweise auf die Klassenladeprogramm unter anderem die folgenden:

  • die durch den Klassenlader geladenen Klassen
  • java.lang.Package die durch die Klassenlader erstellt selbst
  • java.lang.ProtectionDomain durch den Klassenlader erstellt selbst

Alle oben genannten sind zirkuläre Referenzen innerhalb der Klassenlader, die eine Garbage Collection auslösen sollte. Ich bin mir nicht sicher, warum es nicht ist. Weiß jemand, warum die alten Klassenlader auch bei den Zirkelverweisen immer noch nicht Müll sind?

+0

Welche JVM verwenden Sie (genaue Version)? Verwenden Sie JVM-Optionen, die sich auf das Laden von Klassen auswirken können? Benutzt du irgendwelche Sachen von Suns eigenen Implementierungen? Verändert die Anwendung den Byte-Code? ... Welche Umgebung könnte das Laden von Klassen beeinträchtigen? – cafebabe

+1

Nicht im Zusammenhang mit Ihrer Hauptfrage, aber haben Sie etwas wie OSGi in Betracht gezogen, anstatt Ihr eigenes Framework zu erstellen, das Hot Deployment unterstützt? – SteveD

+0

@bfoo In unseren Tests verwenden wir Java 6. Keine JVM-Optionen.Wir verwenden nicht Suns Impl von irgendetwas im einfachsten Fall. Keine Byte-Code-Manipulation. – onejigtwojig

Antwort

15

Ich habe immer gehört, dass Classloader Entlastung problematisch war. Sie sind theoretically Müll gesammelt, wenn es keinen Bezug auf die Objektinstanzen und Klassenentladung ist nicht notwendig, aber in der Praxis scheint es problematischer sein. Subtile Referenzen können undicht werden und verhindern, dass die Classloader zurückgewonnen wird. In Anwendungsservern habe ich nach zahlreichen Implementierungszyklen manchmal eine OutOfMemoryError: PermGen space erhalten.

All das zu sagen, dass ich denke, es gibt irgendwo eine böse Referenz, die verhindert, dass es gesammelt wird - vielleicht ist der Speicheranalysator der Verknüpfung nicht korrekt gefolgt. Es scheint, wie das alles passieren kann, wie in diesen Artikeln beschrieben:

Auch ich weiß nicht genau, was Sie tun, aber wenn Sie können warten JDK 7, könnten Sie sich AnonymousClassLoader ansehen. Sie werden besser eingeführt werden, um dynamische Sprache zu unterstützen, wie in diesem Beitrag erläutert:

ich es Ihnen helfen, hoffen.

+0

Eine Unteranwendung ist sehr einfach. Die einzige Third-Party-Bibliothek, die sie verwendet, ist log4j. Nichts anderes. Der Rest ist die grundlegende JDK-API. Es verwendet auch die ResourceBundle-Klasse, die den Cache behält. Nach dem Aufruf von clearCache() verschwanden diese Verweise, aber es wird immer noch kein Müll gesammelt. Aber Danke für die Antwort :) – onejigtwojig

+0

oh und übrigens, tolle Links! – onejigtwojig

+0

Ich kann nur vorschlagen, mit der einfachsten Sub-App zu versuchen (sagen wir mit einer Klasse) und dann mehr und mehr Klassen und Abhängigkeiten hinzuzufügen, um zu sehen, an welcher Stelle es den GC des Classloaders stoppt. Aber ich weiß, dass es sehr zeitaufwendig sein kann. Übrigens schrieb Frank Kievet auch interessante Beiträge zu XA-Transaktionen, wenn Sie interessiert sind. – ewernli