2010-08-19 6 views
21

Es sieht aus wieTomcat auf Produktionsserver, PermGen und redeploys

MemoryError: PermGen space 
java.lang.OutOfMemoryError: PermGen space 

ist ein häufiges Problem. Sie können die Größe Ihres zulässigen Bereichs erhöhen, aber nach 100 oder 200 erneuten Bereitstellungen ist dieser voll. Das Verfolgen von Speicherlecks im ClassLoader ist nahezu unmöglich.

Was sind Ihre Methoden für Tomcat (oder einen anderen einfachen Servlet-Container - Jetty?) Auf dem Produktionsserver? Wird der Server nach jeder Bereitstellung einer Lösung neu gestartet?

Verwenden Sie einen Tomcat für viele Anwendungen?

Vielleicht sollte ich viele Jetty-Server auf verschiedenen Ports (oder einem eingebetteten Jetty) verwenden und jedes Mal die Bereitstellung rückgängig machen/neu starten/bereitstellen?

+0

Haben Sie versucht, die Größe des Heapspeichers zu erhöhen? – vsingh

+0

Es ist kein Heap-Größenproblem, aber Klassen Bytecode entladen Problem. Sie sagen, dass Klassen in JVM nicht entladen werden und PermGen-Speicherplatz nicht verwischt wird. –

Antwort

6

Ich habe den Tomcat-Manager nicht mehr verwendet und Tomcat immer wieder heruntergefahren.

Wir betreiben zwei Tomcats auf demselben Server und verwenden den Apache-Webserver mit mod_proxy_ajp, so dass Benutzer über den gleichen Port 80 auf beide Apps zugreifen können. Das ist auch gut, weil die Benutzer die Apache-Service-Seite nicht verfügbar sehen, wenn der Tomcat nicht läuft.

+1

Wir verwenden zwei Tomcats an verschiedenen Ports hinter HAProxy, um eine blaugrüne Bereitstellungslösung bereitzustellen. Der "Blaue" Server wird heruntergefahren, wenn "Grün" läuft und HAProxy wechselt dann zu "Grün". Die nächste Bereitstellung wird dann auf "Blau" gesetzt. –

2

Ja tatsächlich, das ist ein Problem. Wir betreiben drei Web-Apps auf einem Tomcat-Server: Nr. 1 verwendet ein Webanwendungsframework, Hibernate und viele andere JARs, nein. 2 verwendet Hibernate und ein paar JARs und keine. 3 ist im Grunde eine sehr einfache JSP-Anwendung.

Wenn wir keine bereitstellen. 1, wir starten Tomcat immer neu. Andernfalls wird uns bald ein PermGen-Platzfehler beißen. Nr. 2 kann manchmal ohne Problem eingesetzt werden, aber da es oft ändert, wenn nein. 1 tut auch, ein Neustart ist sowieso geplant. Nr. 3 ist überhaupt kein Problem und kann problemlos so oft wie nötig eingesetzt werden.

Also, ja, wir starten Tomcat normalerweise neu. Wir freuen uns aber auch auf Tomcat 7, das viele Speicher-/Klassenladeprobleme behandeln soll, die in verschiedenen JARs und Frameworks von Drittanbietern enthalten sind.

3

können Sie versuchen, diese Java-Optionen hinzu:

-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled 

Dies ermöglicht die Garbage Collection in PermGen Raum (standardmäßig deaktiviert) und ermöglicht die GC-Klassen zu entladen. Zusätzlich sollten Sie die -XX: PermSize = 64m -XX: MaxPermSize = 128m an anderer Stelle verwenden, um die verfügbare Menge an PermGen zu erhöhen.

+2

Wie sollen diese helfen? – vsingh

1

Sie sollten PermGen Garbage Collection aktivieren. Standardmäßig wird in der Hotspot-VM KEIN PermGen-Müll gesammelt, was bedeutet, dass alle geladenen Klassendateien für immer im Speicher verbleiben. Bei jeder neuen Implementierung wird eine neue Gruppe von Klassendateien geladen, sodass der PermGen-Speicherplatz möglicherweise nicht mehr ausreicht.

+0

Wie von @Soundlink angegeben, sind die Parameter zum Aktivieren von GC in PermGen "-XX: + CMSClassUnloadingEnabled -XX: + CMSPermGenSweepingEnabled". Unter Ubuntu würden Sie diese zu JAVA_OPTS in/etc/default/tomcat6 hinzufügen. – werkshy

2

PermGen-Switches in HotSpot verzögern nur das Problem, und schließlich erhalten Sie den OutOfMemoryError trotzdem.

Wir hatten dieses Problem eine lange Zeit, und die einzige Lösung, die ich bisher gefunden habe, ist die Verwendung von JRockit statt. Es hat kein PermGen, also verschwindet das Problem einfach. Wir evaluieren es jetzt auf unseren Testservern, und seit dem Wechsel gab es kein PermGen-Problem mehr. Ich habe auch versucht, mehr als 20 Mal auf meinem lokalen Rechner mit einer App zu implementieren, die diesen Fehler bei der ersten erneuten Bereitstellung erhält, und alles lief wunderbar mit.

JRockit soll in OpenJDK integriert werden, daher wird dieses Problem in Zukunft vielleicht auch für Java auf Lager gehen.

http://www.oracle.com/technetwork/middleware/jrockit/overview/index.html

Und es ist kostenlos, unter der gleichen Lizenz wie HotSpot:

https://blogs.oracle.com/henrik/entry/jrockit_is_now_free_and

+0

Ich dachte JRockit hält Klassendefinitionen auf Heap. Wächst Ihr Heap nicht nach jeder erneuten Bereitstellung? Was zeigt "JRockit Mission Control" über die Größe des Heapspeichers? –

+0

Der Heap bleibt nach jeder erneuten Bereitstellung in der gleichen Größe, soweit ich sehen kann. Ich habe es noch einmal mit ungefähr 10 Umsetzungen versucht. –

1

Welche Version von Tomcat verwenden Sie? Tomcat 7 und 6.0.30 haben viele Funktionen, um diese Lecks zu vermeiden, oder warnen Sie zumindest vor ihrer Ursache.

This presentation von Mark Thomas von SpringSource (und langjährige Tomcat Committer) zu diesem Thema ist sehr interessant.

+0

Die Frage wurde 2010 gestellt. Tomcat 7 war damals in Planung. Unsere Lösung war eine Anwendung, die Tomcat herunterfährt, alte WAR in Backup-Verzeichnis kopiert, neue WAR von Hudson herunterlädt, Tomcat startet. Wir verwenden zwei Tomcats und ein blau-grünes Bereitstellungsmuster. –

1

Als Referenz gibt es eine neue Version des Tools Plumbr, die auch Lecks der permanenten Generation überwachen und erkennen kann.