Übermäßiger Speicherverbrauch von Tomcat

7

Ich habe einen neuen Server mit Ubuntu 11.04 (Natty) (64-Bit). Ich begann mit der Installation von openjdkund tomcat6. Beim Start des Tomcat-Servers werden sofort mehr als 480 MB Arbeitsspeicher verwendet. Dies scheint unverhältnismäßig und ich frage mich, ob jemand eine Lösung hat, um Tomcat dazu zu bringen, 200-300 MB (oder weniger) Speicher zu verwenden.

Ich habe memtop verwendet, um Folgendes zu sehen: (Hinweis: Ich habe alle bis auf die großen Einträge entfernt. Der 499-MB-Eintrag ist Tomcat.)

  user@xyz:~# python memtop-0.9.py
  PID |   private/writ. mem |command
      |  current | previous |(truncated)
19776 | 499.3 MB |    +++++ |/usr/lib/jvm/java-6-openjdk/bin/java-Djava.util.logging.config.file=/var/lib/tomcat6/conf/logging.properties-Djava.awt.headless=true-Xm
18082 | 148.6 MB |    +++++ |/usr/sbin/mysqld
 1385 |   3.6 MB |    ++    |pythonmemtop-0.9.py
RAM usage:  ==============================================  69.3 %

Außerdem können Sie sehen, welche JDK- und Tomcat-Pakete ich installiert habe:

user@xyz:~# dpkg --get-selections | grep jdk
default-jdk                                     install
openjdk-6-jdk                                   install
openjdk-6-jre                                   install
openjdk-6-jre-headless                          install
openjdk-6-jre-lib                               install

user@xyz:~# dpkg --get-selections | grep tomcat
libtomcat6-java                                 install
tomcat6                                         install
tomcat6-admin                                   install
tomcat6-common                                  install
tomcat6-user                                    install

Das Startskript für Tomcat ist Xmxauf 128 MB festgelegt :

JAVA_OPTS="-Djava.awt.headless=true -Xmx128M"

Hat jemand eine Idee, was ich tun könnte, um den Speicherverbrauch auf etwas Vernünftigeres zu reduzieren? Ich verstehe nicht, warum JVM und Tomcat zusammen so viel Speicher benötigen würden.

EDITS

Zum Teufel habe ich Tomcat 6 direkt heruntergeladen und das Startskript ausgeführt. Beachten Sie, dass diesmal kein Xmx- Wert festgelegt wurde. Bei der Ausführung dieses, memtop zeigt , dass Tomcat mit 737 MB sind im Wert von Speicher!

Dies lässt mich glauben, dass es ein Problem mit openjdk gibt , das eine ernsthafte Menge an Speicher für die JVM verwendet.


Ich habe das gleiche mit einem neuen .zip-Download von Tomcat 7 versucht - das gleiche Problem. Es wurden 740 MB Speicher verwendet.


Ich habe das Sun JRE / JDK installiert. Der Speicherverbrauch ging von fast 500 MB auf rund 400 MB zurück . Dies ist immer noch mehr Speicher als ich bevorzugen würde!

(sun-java6-bin, sun-java6-jdk, sun-java6-jre)


Wenn ich renne top, bekomme ich folgendes:

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
13749 tomcat6   20   0  481m  68m 9892 S    0  7.4   0:02.85 java

Ich erkenne und erwarte, dass eine 64-Bit-Maschine / JVM mehr Speicher benötigt, aber ich habe nicht erwartet, dass sie so hoch ist. Ich verwende eine VM, die mir nur 512 MB garantiert.

Gerber
quelle
Hm, ich bin auch auf 11.04 64-Bit (nur Laptop). Mein Tomcat 7.0.19 weist zunächst ca. 50 MB zu. Sie haben Vanilla Tomcat oder so etwas wie Jetty, GateIn, Liferay usw. installiert?
Hause
Ja, Vanille Tomcat. Soweit ich das beurteilen kann, sollte es die einfachste und leichteste Installation sein, die möglich ist - zumindest aus Sicht der Paketverwaltung.
Haben Sie vor dem Start des Servers Skripte geändert?
Hause
Nein, die Skripte waren Standard. Vanille wie Vanille sein kann!
2
Vielleicht summiert das Memtop-Tool nur alle Speicherzuordnungen und dergleichen, die zugeordnet wurden. Das wird eine Menge sein, aber nur weil einige Speicherzuordnungen vorgenommen wurden, heißt das nicht, dass sie verwendet werden. Was sagt die Spalte RESund VIRT, wenn Sie verwenden top?
Nr.

Antworten:

2

---- Bearbeitet, um ein Beispiel zu liefern, da der Punkt nicht auftaucht ----

Ein Prozess wird gestartet und fordert 1 GB Speicher an.

Dieser Prozess startet dann acht Threads (die alle Zugriff auf die zugewiesenen 1 GB Speicher haben).

Jemand führt ein Tool aus, um festzustellen, wie viel Speicher verwendet wird. Das Tool funktioniert wie folgt:

  1. Finden Sie jedes planbare Element (jeden Thread).
  2. Sehen Sie, auf wie viel Speicher zugegriffen werden kann.
  3. Addiere diesen Speicher zusammen
  4. Geben Sie die Summe an.

Das Tool meldet, dass der Prozess 9 GB Arbeitsspeicher verwendet, wenn (hoffentlich) offensichtlich ist, dass acht erzeugte Threads (und der Thread für den ursprünglichen Prozess) alle denselben GB Arbeitsspeicher verwenden.

Es ist ein Fehler in der Art und Weise, wie einige Tools Speicher melden. Es handelt sich jedoch nicht um einen leicht zu behebenden Fehler (da für die Behebung die Ausgabe einiger sehr alter (aber wichtiger) Werkzeuge geändert werden müsste). Ich möchte nicht der Typ sein, der top oder ps neu schreibt, es würde das Betriebssystem zu einem Nicht-POSIX machen.

---- Es folgt der ursprüngliche Beitrag ---- Einige Versionen von Speicherberichts-Tools (wie oben) verwechseln fälschlicherweise Threads (die alle Zugriff auf denselben Speicher haben) mit Prozessen. Infolgedessen meldet eine Tomcat-Instanz, die fünf Threads erzeugt, den Speicherverbrauch um das Fünffache.

Die einzige Möglichkeit, dies sicherzustellen, besteht darin, die Prozesse mit ihrem Speicherverbrauch einzeln aufzulisten und dann den Speicher für einen der Threads zu lesen (der wie ein Prozess aufgelistet wird). Auf diese Weise kennen Sie den tatsächlichen Speicherverbrauch der Anwendung. Wenn Sie sich auf Tools verlassen, die das Hinzufügen für Sie durchführen, überschätzen Sie die tatsächlich verwendete Speichermenge durch die Anzahl der Threads, die auf denselben gemeinsam genutzten Speicher verweisen.

Ich hatte Boxen mit 2 GB Speicher (und 1 GB Swap), die berichteten, dass ~ 7 GB Speicher in einer besonders threadlastigen Anwendung verwendet wurden.

Ein besseres Verständnis dafür, wie Speicher von vielen Tools gemeldet wird, finden Sie hier . Wenn der Python-Code den Text eines dieser Tools analysiert oder diese Daten von denselben Systemaufrufen abruft, treten dieselben Fehler im Überberichtsspeicher auf.

Edwin Buck
quelle
Dies könnte eine Möglichkeit sein, aber wie kann ich das sicher wissen? Das Problem, auf das ich stoße, ist, dass die VM anscheinend meine Speichernutzung genauso meldet wie memtopgezeigt. Nach Angaben des Hosting-Unternehmens über- oder überstehe ich meine Speichernutzung.
Sie haben dem JVM gesagt, dass er nicht mehr Heap als X zuweisen soll. so wird es nicht. Abgesehen von einem massiven Fehler in der JVM, den nur Sie bemerkt haben, wie würden Sie sonst erklären, dass die JVM ihre Konfigurationsparameter nicht berücksichtigt? Rufen Sie mich erschöpft an, aber ich denke, andere (einschließlich ich) würden mit Heugabeln und Taschenlampen vor den Büros von Oracle stehen, wenn diese offensichtliche (und betriebskritische) Funktionalität nicht funktioniert.
Edwin Buck
Ja, ich habe die maximale Heap-Größe angegeben, aber dies ist nicht der einzige Speicher, den die JVM verwendet. java-espresso.blogspot.com/2011/05/heap-structure-in-jvm.html
Das stimmt jedoch, dass die anderen Elemente im Vergleich zu einem beträchtlichen Heap so wenig Overhead enthalten, dass Sie nicht in Gefahr sind, zu beobachten, wie Ihre JVM auf das Sechsfache der Größe des Heaps wächst (so wie Sie sind).
Edwin Buck
Sie sagen also, es hört sich so an, als würde das -Xmx=128Mnicht geehrt?