JRockit und fragmentierter Heap
Der Heap in einer JVM fragmentiert durch das Allokieren von Speicher für Objekte von unterschiedlicher Größe und Lebenszeit. Besonders problematisch ist dies beim Hochladen von großen Dateien. Sichtbar wird dies durch folgenden Logfile-Eintrag:
java.lang.OutOfMemoryError: allocLargeObjectOrArray - Object size: 262160, Num elements: 262144
In diesem Fall wurde vergeblich versucht 262160 Byte zu allokieren.
Was kann man tun?
Unter [1] findet sich eine wertvolle Anleitung. Hier die Infos, was wir gemacht haben:
- Heapsize anpassen, ich bin jedoch kein Freund eines zu großen Heaps, da dies sehr lange GC Zyklen zur Folge hat. Es ist meistens besser in einem Cluster einen weiteren WebLogic Server hinzuzufügen, als den Heap zu groß zu wählen. Wir haben folgende Settings gewählt: -Xms1356m –Xmx1356m
- Um sicherzustellen, dass der WebLogic Server Nodemanager die JRockit automatisch bei einem OutOfMemoryError starten kann, haben wir den Schalter –XxexitOnOutOfMemory benutzt. Hierbei bendet sich die Jrockit automatisch und läuft nicht in einem halbtoten Zustand weiter.
- Um die GC überwachen zu können haben wir diesen Schalter hinzugefügt -Xverbose:gcpause
- Ein weiterer wichtiger Parameter ist die Verdichtung des freien Heaps, sprich eine Defragmentierung. Hierbei sollte vorsichtig vorgegangen werden. Wir haben uns für folgenden Wert entschieden: -XXcompactratio=10
- Des Weiteren haben wir noch die Generational GC mit -Xgc:gencon gesetzt.
Hier die gesamte Parameterliste:
-Xms1356m –Xmx1356m -Xgc:gencon –XxexitOnOutOfMemory -Xverbose:gcpause
Noch eine Anmerkung zur Heapsize. In unserem Fall handelte es sich um einen Windows 2003 Server mit 16GByte Memory und eingeschalteter (Physical Address Extension)PAE .
Unter [2] findet sich eine interessante Info bzgl. Speicherverfügbarkeit von JRockit unter Windows mit PAE. JRockit hat hier gegenüber der Sun JVM den Vorteil, dass der Speicher nicht zusammenhängend sein muss. Jedoch muss hier beachtet werden, dass in einem JRockit Prozess auch etwaige DLLs von nativen Java Bibliotheken (z.B. SAPJco oder Documentum) liegen. Dies war bei uns der Fall.