Hintergrund
Wir haben einen Pool von etwa 20 Linux-Blades. Auf einigen läuft Suse, auf einigen Redhat. Alle teilen sich einen NAS-Speicherplatz, der die folgenden 3 Ordner enthält:
- /NAS/app/java - ein Symlink, der auf eine Installation eines Java JDK verweist. Derzeit Version 1.5.0_10
- /NAS/app/lib - ein Symlink, der auf eine Version unserer Anwendung verweist.
- /NAS/data - Verzeichnis, in das unsere Ausgabe geschrieben wird
Alle unsere Rechner haben 2 Prozessoren (Hyperthreading) mit 4 GB physischem Speicher und 4 GB Swap-Speicher. Wir begrenzen die Anzahl der "Aufträge", die jeder Rechner gleichzeitig verarbeiten kann, auf 6 (diese Zahl muss wahrscheinlich geändert werden, aber das spielt bei dem aktuellen Problem keine Rolle, also ignorieren Sie es bitte vorerst).
Einige unserer Aufträge legen eine maximale Heap-Größe von 512 MB fest, andere wiederum reservieren eine maximale Heap-Größe von 2048 MB. Auch hier ist uns klar, dass der verfügbare Arbeitsspeicher überschritten werden könnte, wenn 6 Aufträge auf demselben Rechner mit einer Heap-Größe von 2048 gestartet würden, aber das ist unseres Wissens noch nicht vorgekommen.
Das Problem
Es kommt vor, dass ein Auftrag sofort mit der folgenden Meldung fehlschlägt:
Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.
Früher haben wir das auf zu viele gleichzeitig laufende Aufträge auf demselben Rechner geschoben. Das Problem trat selten genug auf ( MAYBE einmal im Monat), dass wir es einfach neu starten würden und alles in Ordnung wäre.
Das Problem hat sich in letzter Zeit noch verschlimmert. Alle unsere Aufträge, die eine maximale Heap-Größe von 2048m anfordern, schlagen fast jedes Mal sofort fehl und müssen mehrmals neu gestartet werden, bevor sie abgeschlossen werden können.
Wir sind zu den einzelnen Rechnern gegangen und haben versucht, sie manuell auszuführen - mit demselben Ergebnis.
Fehlersuche
Es stellte sich heraus, dass das Problem nur bei unseren SuSE-Boxen besteht. Der Grund dafür, dass es häufiger auftritt, ist, dass wir mehr Rechner hinzugefügt haben, und die neuen sind SuSE.
cat /proc/version' auf den SuSE-Boxen liefert uns:
Linux version 2.6.5-7.244-bigsmp (geeko@buildhost) (gcc version 3.3.3 (SuSE Linux)) #1 SMP Mon Dec 12 18:32:25 UTC 2005
cat /proc/version' auf den RedHat-Rechnern liefert uns:
Linux version 2.4.21-32.0.1.ELsmp (bhcompile@bugs.build.redhat.com) (gcc version 3.2.3 20030502 (Red Hat Linux 3.2.3-52)) #1 SMP Tue May 17 17:52:23 EDT 2005
uname -a' gibt uns auf BEIDEN Rechnertypen folgendes an:
UTC 2005 i686 i686 i386 GNU/Linux
Auf dem Rechner laufen keine Aufträge, und keine anderen Prozesse belegen viel Speicher. Alle derzeit laufenden Prozesse könnte insgesamt 100 MB verbrauchen.
top" zeigt derzeit Folgendes:
Mem: 4146528k total, 3536360k used, 610168k free, 132136k buffers
Swap: 4194288k total, 0k used, 4194288k free, 3283908k cached
vmstat' zeigt derzeit Folgendes an:
procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
0 0 0 610292 132136 3283908 0 0 0 2 26 15 0 0 100 0
Wenn wir einen Auftrag mit der folgenden Befehlszeile starten (maximaler Heap von 1850 MB), startet er problemlos:
java/bin/java -Xmx1850M -cp helloworld.jar HelloWorld
Hello World
Wenn wir die maximale Heap-Größe auf 1875 MB erhöhen, schlägt es fehl:
java/bin/java -Xmx1875M -cp helloworld.jar HelloWorld
Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.
Es ist ziemlich klar, dass der derzeit verwendete Speicher für die Zwischenspeicherung verwendet wird und deshalb so wenig als "frei" angezeigt wird. Was nicht klar ist, ist, warum es eine magische Grenze von 1850 MB gibt, bei der alles, was darüber liegt, bedeutet, dass Java nicht starten kann.
Für Erklärungen wären wir Ihnen sehr dankbar.