6 Stimmen

PermGen-Speicherplatzproblem mit Glassfish/Hibernate

Ich führe eine GWT+Hibernate-Anwendung auf Glassfish 3.1 aus. Nach ein paar Stunden geht mir der Permgen-Speicherplatz aus. Dies geschieht ohne dass die Webapp neu geladen wird. Ich laufe mit –XX:MaxPermSize=256m –XmX1024m .

Ich habe den Rat von diese Seite und festgestellt, dass ich Tonnen von Klassen - alle meine Hibernate-Modelle und alle meine GWT RequestFactory-Proxies - auslaufen lasse.

In dem oben erwähnten Leitfaden heißt es: "Überprüfen Sie die Ketten, finden Sie den versehentlichen Verweis, und beheben Sie den Code". Leichter gesagt als getan.

Der Classloader verweist immer zurück auf eine Instanz von org.glassfish.web.loader.WebappClassLoader . Wenn ich weiter recherchiere, finde ich viele Referenzen von $Proxy135 und ähnlich benannte Objekte. Aber ich weiß nicht, wie ich sonst weitermachen soll.

22voto

Dead Programmer Punkte 12177

Werden neue Klassenobjekte in das PermGen eingefügt und nehmen so immer mehr Platz ein. Unabhängig davon, wie groß Sie den PermGen-Speicherplatz machen, wird er nach einer ausreichenden Anzahl von Implementierungen unweigerlich voll sein. Sie müssen Maßnahmen ergreifen, um den PermGen-Speicherplatz zu leeren, damit Sie seine Größe stabilisieren können. Es gibt zwei JVM-Flags, die diese Bereinigung vornehmen:

-XX:+CMSPermGenSweepingEnabled

Mit dieser Einstellung wird der PermGen in einen Garbage Collection-Lauf einbezogen. Standardmäßig wird der PermGen-Bereich nie in die Garbage Collection einbezogen (und wächst daher unbegrenzt).

-XX:+CMSClassUnloadingEnabled

Diese Einstellung teilt dem PermGen Garbage Collection Sweep mit, dass er bei Klassenobjekten aktiv werden soll. Standardmäßig werden Klassenobjekte ausgenommen, auch wenn der PermGen-Bereich während einer Garbage Collection besucht wird.

4voto

Craig Ringer Punkte 280068

Es gibt einige OK-Tools, die dabei helfen, auch wenn man es nicht merkt. Das JDK (1.6 u1 und höher) wird mit jhat und jmap ausgeliefert. Diese Tools sind eine große Hilfe, insbesondere wenn Sie die JavaScript-Abfrageunterstützung von jhat verwenden.

Siehe:

http://blog.ringerc.id.au/2011/06/java-ee-application-servers-learning.html

http://blogs.oracle.com/fkieviet/entry/classloader_leaks_the_dreaded_java

http://www.mhaller.de/archives/140-Memory-leaks-et-alii.html

http://blogs.oracle.com/sundararajan/entry/jhat_s_javascript_interface

4voto

George Armhold Punkte 30314

Ich habe dieses Problem durch den Wechsel zu Tomcat "gelöst".

2voto

Preston Punkte 3263

(Ich kann den Link, den Sie angegeben haben, nicht sehen, da er von Websense blockiert wird, also entschuldige ich mich, wenn ich etwas wiederhole)

Es hört sich an, als hätten Sie ein Leck im Klassenlader. Diese sind schwer aufzuspüren, fügen Sie diese Optionen zu den JVM-Optionen in Ihrer Instanzkonfiguration hinzu

-XX:+PrintGCDetails
-XX:+TraceClassUnloading
-XX:+TraceClassLoading

Wenn Sie nun Ihre Anwendung ausführen, können Sie sich das jvm.log in Ihrem domain/logs-Ordner ansehen und sehen, was geladen und entladen wird. Höchstwahrscheinlich werden Sie sehen, dass dieselbe(n) Klasse(n) immer wieder geladen wird (werden).

Ein guter Übeltäter ist JAXB, insbesondere wenn Sie immer wieder einen neuen JAXBContext erstellen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X