Wie bereits erwähnt, treten wahrscheinlich undichte Klassenlader auf. Aus irgendeinem Grund werden Ihre Klassen nicht entladen. Dies kann aus zwei Gründen geschehen
- Objekte dieser Klassen sind noch auf dem Heap vorhanden, Objekte verweisen immer auf ihre Klasse oder
- Der Klassenlader wird irgendwo referenziert, aus welchem Grund auch immer, Klassenlader verweisen auf ihre Klassen, um sie nicht zweimal zu laden
Es gibt keine umfassende Lösung für dieses Problem. Ein hilfreiches Tool zum Auffinden der Hauptursache ist das Eclipse Memory Analyzer-Tool , das Sie auf einen Heap-Dump aus Ihrer JVM anwenden können (Sie können Heap-Dumps in OOMs mit der Option -XX: + HeapDumpOnOutOfMemoryError aktivieren). Suchen Sie möglicherweise in Ihrer Web-App nach java.lang.Class-Objekten, um festzustellen, warum sie am Leben bleiben. Leider ist PermGen normalerweise nicht Teil eines JVM-Heap-Dumps, so dass Sie nur versuchen können, korrelierende Artefakte im Rest des Heaps zu finden (Klassenobjekte werden nicht in PermGen gespeichert, wenn ich mich nicht irre, nur der tatsächliche Bytecode ist, bitte korrigiere mich, wenn ich falsch liege).
HTH.
Bearbeiten:
Dave Cheney schlägt in einem Kommentar vor, dass java.lang.Class-Objekte tatsächlich Teil von PermGen sind und nicht in einem normalen Hotspot-Heap-Dump enthalten sind. Sofern Sie keine JVM haben, die diese Informationen in den Heap-Dump schreibt, benötigen Sie einen anderen Ansatz. Sie können immer noch nach Instanzen Ihrer Objekte suchen, aber wenn Sie Klassen / Klassenlader verlieren (beide implizieren sich leider gegenseitig), müssen Sie anscheinend nach anderen Zeichen suchen (Metadatenobjekte von JBoss usw.).
Die zugrunde liegende Ursache sind Verweise auf Klassen, die verworfen wurden und außerhalb ihres Klassenladeprogramms lecken, wodurch verhindert wird, dass die JVM diese Klassen aus dem Perm entlädt. Diese Flags , die Sie verwenden , um die JVM zu aggressiv Säuberung Klassen verursachen, sind unloadable, aber es wird das zugrunde liegende Problem nicht lösen.
Es gibt eine gute, abeit komplexe Erklärung hier
quelle
Die Ursache für den PermGen OutOfMemory-Fehler ist die erneute Bereitstellung der App. Die zugrunde liegende Ursache sind durchgesickerte Klassenobjekte in PermGen aus den erneuten Bereitstellungen.
Die Problemumgehung besteht natürlich darin, die JVM nach einer bestimmten Anzahl von erneuten Bereitstellungen neu zu starten.
Dies ist ein sehr schwer zu lösendes Problem, obwohl Sie mit einigem Hin und Her oft große Verbesserungen erzielen können. Hier fangen Sie an: Wenn Ihre Web-App gestoppt ist, stellen Sie Folgendes sicher:
Dies sind einige der Dinge, die dazu führen können, dass ein Klassenobjekt in PermGen eingeschlossen wird.
Beachten Sie außerdem, dass nicht alle JVMs (oder alle Versionen von JVMs) GC-Klassenobjekte in PermGen verwenden. Wenn Sie eine JVM oder eine Version einer JVM ausführen, die keine Objekte der GC-Klasse in PermGen enthält, können Sie die JVM nach einer bestimmten Anzahl von Neubereitstellungen nur neu starten. Dies trifft angesichts der von Ihnen erwähnten JVM-Optionen wahrscheinlich nicht auf Sie zu.
quelle