Mehrere JVM-Instanzen auf einem Rechner belegen zu viel Speicher

SlowMoe

Grünschnabel
Hallo Javagemeinde,

ich beschreibe zunächst mal das verwendete System:
Ein debian etch (32Bit) mit einem JDK 1.5.0-16 und 5GB Ram, Swap sind nochmal 4GB. Auf diesem Rechner laufen gleichzeitig 7 (sieben) JVMs. Alle sind mit -Xmx und -Xms auf 512m beschränkt (manche auch 256m). In den JVM laufen embedded Tomcats und einige WebApps.

Nun zum eigentlichen Problem: im top ist zu sehen, dass der RESIDENT Speicher deutlich über den festgelegten Werten liegt. Der VIRTUAL Speicher legt da nochmal einige hundert MB drauf.
Resultat: Der Server swapped und wird damit unglaublich langsam.

Wir haben festgestellt, dass der belegte Speicher auch auf einem 32Bit Windows XP über den vorgegebenen Grenzen liegt, allerdings steigt er hier nur bis zu einem gewissen Grad, bleibt dort wie festgenagelt und gibt seinen Speicher auch wieder frei. Dies geschieht unter Linux nie.

Frage: Ist es normal das Linux derartig zuläuft? Gibt es vielleicht eine Art natürliche Beschränkung, so dass gleichzietig nicht mehr als X JVMs laufen sollen? Gibt es ein Fix für diese Art von Problem (ein anderes JDK möglicherweise)?

Das Problem ist leider sehr dringlich und ich wäre um jeden Gedanken sehr dankbar.

Gruß
SlowMoe
 
Hallo,

Nun zum eigentlichen Problem: im top ist zu sehen, dass der RESIDENT Speicher deutlich über den festgelegten Werten liegt. Der VIRTUAL Speicher legt da nochmal einige hundert MB drauf.
Resultat: Der Server swapped und wird damit unglaublich langsam.

den vsz/ rss virtual / resident bzw. Angaben in PS/Top kann man meistens nicht so ganz glauben:
http://virtualthreads.blogspot.com/2006/02/understanding-memory-usage-on-linux.html
Dort sind dann nämlich oftmals auch die shared libs eingerechnet welche sich mehrere Prozesse gemeinsam teilen.

Welche Tomcat Version verwendest du denn? Hostest du den Tomcat wirklich in einer anderen Applikation (=embedded)? Verwendest du class data sharing? Ist da wirklich so viel Traffic auf den Webapps das die einzelnen Tomcats so viel Speicher ziehen müssen? Können bestimmte einfache Webapps vielleicht auf einem Tomcat zusammen laufen?
Sind da noch viele native Bibliotheken (über jni) involviert? Sieht für mich eher nach einer Fehlkonfiguration des Tomcats aus... ist jeder Tomcat individuell den Lastanforderungen entsprechend konfiguriert worden oder hat man hier überall die defaults gelassen?

Gibt es vielleicht eine Art natürliche Beschränkung, so dass gleichzietig nicht mehr als X JVMs laufen sollen?
Nicht das ich wüsste...

Gruß Tom
 
Hi Tom,

danke für deine schnelle Antwort. Der Tomcat wird innerhalb vom Apache Framework OfBiz gehostet (http://ofbiz.apache.org). Wir haben die aktuellsten Tomcat JARs daneben gelegt (6.0).

Es ist schon etwas Traffic auf den einzelnen WebApps, aber es sollte nicht zu dem Problem führen.

Der embedded Tomcat lässt sich nicht direkt über eine server.xml konfigurieren. Die Container.XML hat einige Parameter die wir schon entsprechend angepasst und im Zuge des Testings verändert haben. Am interessantesten sind die MinSpare, MaxSpare und ThreadSize die auf max 128, und min 32 gestellt wurden.
Soweit ich weiss, sind keine native Bibliotheken eingebunden.

Wenn wir Traffic simulieren, also viele Sessions erzeugen und einige Links klicken (wget+ Grinder) und die Webapps intern noch mit einigen Jobs quälen steigt der Speicher weiter und weiter und wird nie wieder an das System zurück gegeben.

Vielleicht noch wichtig zu erwähnen: Allen Tomcats ist ein gemeinsamer Apache vorgeschaltet und der einzig konfigurierte Connector ist der AJP/13.

Nur warum wächstder Speicher ins unermessliche? Ein JVM-Prozess hat im top (danke für den Link übrigens) RES 1,2GB bei einem Xmx/Xms von 512.
 
Zuletzt bearbeitet:
Hallo,

hmmm, habt ihr da schon mal einen Profiler mitlaufen lassen? Vielleicht habt ihr ein Memory Leak in eurem oder im OFBiz / Tomcat code... schau doch mal wo in den einzelnen Prozessen der Speicher "verbraten" wird.

Gruß Tom
 
So, das Problem hat sich nun weitgehend erledigt. Hier was geholfen hat:

Im OfBiz gibt es ein Flag, welches DebugInformationen loggt. Dies geschieht unheimlich häufig und bei jedem loggen, wird ein neuer Thread erzeugt. Der Tip mit dem Profiler war also goldrichtig, da wir sehen konnten, das bereits nach wenigen Minuten mehr als 20.000+ Threads (Total started) gelaufen sind, Live-Threads hingegen bei mageren 50-100.
Nach dem wir dieses Debug-Logging entfernt haben, wurden auch weniger Threads erstellt und der Speicherhunger liegt nun innerhalb der definierten Grenzen.

Nach etwas Recherche, habe ich herausgefunden, dass ein gestarteter Thread seinen belegten Speicher nicht wieder hergibt. Das würde aber doch bedeuten, dass jede JAVA-Anwendung nur eine gewisse maximale Zeit laufen kann. Kann das sein?

Ich sehe das Thema jedoch erstmal als erledigt und möchte mich nochmals bei Tom bedanken.
 
Zurück