Java JIT Compiler verursacht OutOfMemoryError

Eine Anwendung, die vor kurzem sporadisch mit der Meldung "java.lang.OutOfMemoryError: angeforderte 8589934608 Byte für Chunk :: new. Nicht genügend Auslagerungsspeicherplatz?" Abgestürzt ist.

Ich habe mich im Internet umgesehen und überall sind Vorschläge auf @ beschränk

Zu einer früheren Java-Version zurückkehren Geige mit den Speichereinstellungen Client anstelle des Servermodus verwenden

Um auf eine frühere Version zurückzugreifen, bedeutet, dass das neue Java einen Fehler aufweist, aber ich habe keine Hinweise darauf gesehen. Das Gedächtnis ist überhaupt kein Thema; Auf dem Server sind 32 GB verfügbar, und Xmx ist auf 20 festgelegt, während Xms auf 10 festgelegt ist. Die verbleibenden 12 GB der JVM (abzüglich des Betrags, der für die wenigen anderen Prozesse auf dem Computer angegeben wurde) gehen nicht aus. Und wir bleiben aufgrund der Art der Anwendung und der Umgebung beim Servermodus.

Wenn ich mir die Speicher- und CPU-Auslastung der Anwendung anschaue, sehe ich eine konstante Speicherauslastung für den gesamten Tag, aber dann geht die CPU-Auslastung plötzlich auf 100% und die Speicherauslastung von X auf X + 2 GB , zu X + 4GB, zu (manchmal) X + 8GB, zu JVM Tod. Es scheint, dass in der JIT-Kompilierung möglicherweise ein Zyklus wiederholter Array-Größenänderungen stattfindet.

Ich habe jetzt gesehen, dass der Fehler bei der obigen 8GB-Anfrage und auch bei 16GB-Anfragen auftritt. In jedem Fall ist die Methode, die in diesem Fall kompiliert wird, dieselbe. Es handelt sich um eine einfache Methode mit nicht verschachtelten Schleifen und keiner Rekursion. Sie verwendet Methoden für Objekte, die statische Elementfelder oder Instanzelementfelder mit geringem Rechenaufwand direkt zurückgeben.

So habe ich 2 Fragen:

Hat jemand Vorschläge?Kann ich testen, ob beim Kompilieren dieser bestimmten Methode in einer Testumgebung ein Problem auftritt, ohne die gesamte Anwendung auszuführen und den JIT-Compiler direkt aufzurufen? Oder sollte ich die Anwendung starten und sie anweisen, Methoden nach einer viel geringeren Anzahl von Aufrufen (wie 2) zu kompilieren, um sie zu zwingen, die Methode fast sofort zu kompilieren, anstatt zu einem zufälligen Zeitpunkt am Tag?

@ StephenC

Die JVM ist 1.6.0_20 (zuvor 1.6.0_0) und wird unter Solaris ausgeführt. Ich weiß, dass es die Zusammenstellung ist, die aus mehreren Gründen ein Problem verursacht.

ps in den Sekunden davor zeigt an, dass ein Java-Thread mit der ID, die dem Compiler-Thread (von jstack) entspricht, 100% der CPU-Zeit in Anspruch nimmtjstack zeigt das Problem ist inJavaThread "CompilerThread1" daemon [_thread_in_native, id=34, ...]

Die in @ erwähnte Methojstack ist immer dasselbe und wir haben es geschrieben. Wenn Sie sich sample @ ansehjstack output Sie wissen, was ich meine, aber aus offensichtlichen Gründen kann ich keine Codebeispiele oder Dateinamen bereitstellen. Ich werde sagen, dass es eine sehr einfache Methode ist. Es gibt eine Handvoll Nullprüfungen, zwei für Schleifen, die Gleichheitsprüfungen durchführen und möglicherweise Werte zuweisen, und einige einfache Methodenaufrufe danach. Alles in allem vielleicht 40 Codezeilen.

Dieses Problem ist zweimal in 2 Wochen aufgetreten, obwohl die Anwendung jeden Tag ausgeführt und täglich neu gestartet wird. Außerdem war die Anwendung zu keiner dieser Zeiten stark ausgelastet.

Antworten auf die Frage(6)

Ihre Antwort auf die Frage