Veröffentlicht von & unter ColdFusion.

Maximum JVM Heap Size & Co

Auf 32 Bit Maschinen können für einen Prozess maximal 1,8GB allokiert werden. ColdFusion unter JRun nutzt in der Standardkonfiguration allerdings nur 512MB. Damit ColdFusion diese physikalischen Grenzen auch ausnutzt, muss in der jvm.config der Speicher erst bereitgestellt werden. In der /cfRoot/runtime/bin/jvm.config muss unter „# Arguments to VM“ der Xmx Parameter entsprechnend eingestellt werden.

Beispiel: -Xmx1024m ( für 1Gig )

Wird ein Wert über 1,8GB eingestellt startet die Instanz nicht mehr. Unter Linux kommt folgende Fehlermeldung:

Error occurred during initialization of VM
Could not reserve enough space for object heap

Die 1,8GB ist aber auch nur ein theoretischer Wert. In der Praxis schafft man meistens nicht mehr als 1,6GB zu allokieren. Wer allerdings glaubt, seine Applikation wird mit dem mehr an Speicher schneller und besser laufen, der irrt. Ein zu hoher oder zu niedriger Wert der „total Heap“ oder „Perm Heap“ entwickelt sich schnell zur Performance Falle. Die optimalen Werte für seine Applikation zu finden, ist bereits eine Kunst für sich. Um optimale Werte zu erhalten, ist der Server bzw. das Cluster entsprechend zu belasten z.B. mit dem StressTool. Aktivieren der Metricsdaten helfen dem Speicher,Threads und Sessions etc. zu überwachen. Das Tool JVMSTAT von Sun logt JVM und Garbage Collector Daten.Nutzt eine Anwendung nicht den ganzen Speicher aus, so ist jedes Kilobyte zu viel reine Zeitverschwendung. Benutzt eine Applikation z.B. maximal 512MB sollte die Heap Size auch nicht viel größer gesetzt werden. Mit jedem Kilobyte mehr, was nicht genutzt wird, ist Zeit verschwendet. Das Verwalten des Speichers und der Sessions verschlingen dann zu viel Performance (s.Erklärung JVM Heap).Wer unter Linux & Windows gute Leistung erzielen will, der setzt auf mehrere ColdFusion Instanzen mit ermittelten Werten für die jvm.config. So läuft jede Instanz in ihrem geschlossenen Bereich und der Speicher und die CPU-Last werden optimal verteilt.

Erklärung JVM Heap
Der JVM Heap wird benutzt, um Java Classes und Objekte zu speichern. Er ist aufgeteilt in mehrere Bereiche, die unterscheiden zwischen älteren/neueren Objekten und denen, die oft/selten benutzt werden. Das Sortieren der Objekte passiert während der Garbage Collection. Je nach Systemkonfiguration startet die Garbage Collection mal öfter mal weniger oft. Während die Garbage Collection läuft, werden alte Objekte zerstört und zwischen oft und selten benutzten Objekten sortiert. Eine gute Vorgehensweise ist die JVM Heap bei 512 zu belassen und nicht auf maximal zu stellen. Erst nach Performancetests sollte man sich dann an den optimalen Wert rantasten. Die „iniatial Heap Size“ sollte zu Testbeginn auf den gleichen Wert gestellt werden. So braucht die JVM die Größe nicht immer anzupassen, was Performance kostet. Wird die Heap Size zu klein eingestellt kann es vorkommen, dass ein Objekt angelegt werden soll, das keinen Platz mehr hat. Ist kein Platz mehr da, läuft die Garbage Collection an und räumt auf. Ist nach dem Aufräumen immer noch kein Speicher vorhanden läuft der Server sicht tot und crasht :o/  Ist die HeapSize zu groß eingestellt, wird der Speicher mit einer Menge Objekten bis zum Rand gefüllt, was zufolge hat, dass die Garbage Collection sehr viel zum Aufräumen hat, was sich in einer verminderten Performance niederschlägt. Man sollte die Belastung der Garbage Collection nicht unterschätzen. Ich habe schon von Clustern gehört, die nichts mehr verarbeiten,  weil die Garbage Collection alle Resourcen belegt hat.

Erklärung MaxPermSize (Permanent Generation)
Eine gute Erklärung ist auf der Sun FAQ Site zu finden. Kurz gesagt: die „permanent Generation“ beinhaltet Informationen über Objekte im Heap. Jetzt wird klar, wie die Werte zueinander stehen, oder? Der Heap speichert Objekte und die permanent Generation merkt  sich Informationen über diese Objekte. Summa summarum: je mehr Objekte im Heap liegen desto mehr Informationen fallen an, die im Permanent Generation vorgehalten werden müssen. Wer also die Heap erhöht, sollte auch die permSize erhöhen.In der Sun Dokumentation ist Folgendes zu finden:

Für die meisten Applikationen ist die permanent Generation nicht relevant für die Garbage Collection Performance. Einige Applikationen generieren und laden viele Class Files. Ein Beispiel wären Java Server Pages (JVP), die viele Classes generieren und dynamisch aufrufen. Nach Möglichkeit sollte die permanent Generation Größe mit MaxPermSize größer eingestellt werden.

Dies trifft natürlich auf für ColdFusion zu. Liegen viele Class Files in ../WEB-INF/cfclasses/ muss man die MaxPermSize größer einstellen. Dieser Logik zur Folge kann die MaxPermSize bei Applikationen mit sehr vielen Class Files größer eingestellt werden als bei Applikationen, die nur einige große Classes verwenden. Ein interessanter Artikel ist auf http://www.macromedia.com/go/tn_18540  zu finden.