2009-10-30 29 views
22

Was ich normalerweise in Bezug auf die Größe des jvm-Heapspeichers tun muss, ist, den Maximalwert wirklich hoch zu setzen, um die berüchtigte OutOfMemoryException zu vermeiden.Wie wählt man die jvm-Heap-Größe?

Allerdings scheint diese Strategie (oder fehlende Strategie) nicht wirklich schlau zu sein. :-).

Meine Frage ist, wie die Min- und Max-Werte zu wählen sind, und den Unterschied zwischen den beiden (sollte max-min klein oder groß sein?). Zum Beispiel von here:

, wenn die Anfangshaufen zu klein ist, wird die Java Start der Anwendung langsam als die JVM Garbage Collection zu einer bis hat der Haufen gewachsen häufig auszuführen gezwungen wird angemessene Größe. Für einen optimalen Start Leistung sollten Sie die ursprüngliche Heap-Größe auf die gleiche Größe wie die maximale Heap-Größe setzen.

danke.

Antwort

18

Meine Frage ist, wie die min und Max-Werte zu wählen, und die Differenz zwischen den beiden (sollte max-min klein oder groß sein?)

Kurze Antwort: don Raten Sie nicht, profilieren Sie Ihre Bewerbung.

jconsole can give you useful high-level data wie ein Gefühl für die Haupt-Resident-Set im Vergleich zu den transienten Daten, die wir normalerweise zuweisen und Müll sammeln. Was Sie sehen werden, wenn Sie auf die Speicherregisterkarte dieses Displays schauen, ist normalerweise etwas wie ein Sägezahn. Die untere Ecke der Sägezähne ist ungefähr dort, wo ich normalerweise den Haufen als Minimum festlegen würde, während ich den Gipfel oder die Neigung der Sägezähne verwenden würde, um mit einem Haufenmaximum zu experimentieren. Wenn Ihre Zähne sehr steil sind, könnten Sie einen großen Haufen in Erwägung ziehen, um die Müllsammlung zu verzögern. Wenn dies jedoch nicht der Fall ist, könnten Sie versuchen, ein kleineres Heap-Maximum zu verwenden, um zu sehen, ob das möglicherweise mehr Ressourcen für andere Prozesse auf Ihrem Computer übrig lässt (zum Beispiel).

Sie sollten auch die server VM betrachten, da dies ein anderes Speicherbereinigungsverhalten verursacht.

Alles, was gesagt wurde, sollten Sie auch ein detaillierteres Tool wie jvisualvm to profile the memory usage of your process verwenden. Es ist möglich, dass Sie ein Speicherleck oder einen gierigen Allokator haben, den Sie abstimmen oder eliminieren könnten. Das würde Ihre Heap-Anforderungen komplett ändern.

+0

Danke für alle Referenzen – LB40

+1

@LB, kein Problem. Ich benutze diese Werkzeuge buchstäblich jeden Tag. Zitier mich selbst: "Sie saugen nicht." ;-) –

2

Die richtige Antwort lautet: Es gibt keine richtige Antwort jedes Projekt ist anders und Sie müssen Ihre Heap-Size-Konfiguration auf einer pro-Projekt-Basis Feinabstimmung. Ich würde klein beginnen und schrittweise die Größe des Heapspeichers erhöhen, bis Ihre Anwendung wie gewünscht ausgeführt wird.

Sie haben Recht, die Einstellung eines maximalen Wertes ist keine gute Idee.

+0

und gibt es eine Beziehung zwischen der minimalen und maximalen Größe? Oder ist die Min-Heap-Größe völlig irrelevant? – LB40

+0

Das Min ist * irgendwie * irrelevant, wenn Sie sicherstellen, dass genügend physischer Speicher vorhanden ist, so dass die JVM-Anforderungen für die maximale Heap-Größe immer berücksichtigt werden können.Ich würde sagen, die minimale Größe auf die Art von Heap-Größe setzen, die Sie im normalen Betrieb erwarten (um zu vermeiden, dass die Größe beim Start wiederholt geändert wird), und das Maximum sollte darüber eine "Pufferzone" reflektieren. –

+0

Ich versuche nicht und errate das Betriebssystem/Kernel. Ich muss annehmen, dass sie die Speicherzuweisung gut im Griff haben, persönlich nie ein nachteiliges Problem mit der Größe der JVM gesehen haben und den Parameter -Xms fast ganz ignorieren. – Xailor

5

Sie sollten die GC-Protokollierung aktivieren und prüfen, wo sich Ihr OOM befindet.

-verbose:gc 
-Xloggc:gc.log 
-XX:+PrintGCTimeStamps 
-XX:+PrintGCDetails 

Sie können zul Raumgrenzen werden, dann passen Sie über -XX:MaxPermSize=YYYm

Wie auch immer Ihre Frage zu beantworten, beginne ich ohne Mindest und stellen die maximale relativ hoch. Ich zeichne dann das GC Log und finde heraus wo mein Stead State ist; Wählen Sie visuell eine überdurchschnittliche Größe für die verschiedenen Generationen. Lesen Sie es wie eine Finanz-Chart, Sie wollen eine gute Verbreitung in den neuen Generationen und eine konsequente Wachstum und Sammlung in der festen Generation sehen. Wie bereits erwähnt, zeichnen Sie auch Ihren Dauerwellenraum auf, um sicherzustellen, dass Sie nicht ständig zunehmen.

GC-Tuning ist eine Kunst, in keiner Weise eine Wissenschaft.

+2

"GC Tuning ist eine Kunst, in keiner Weise eine Wissenschaft." Epic, ich zitiere Sie ... – LB40

2

Wenn Sie ein OOME erleben, würde ich tatsächlich beginnen, indem Sie den maximalen Speicher so viel wie möglich erhöhen, und sehen, ob das das Problem löst. Lassen Sie Ihre Maschine zuerst das Leistungsproblem in sich aufnehmen. Wenn das Problem weiterhin besteht, können Sie in die Leistungsdiagnose Einsicht nehmen, um Engpässe zu erkennen und an den Bereichen zu arbeiten, in denen Ihre App möglicherweise undicht ist oder die meiste Speicherkapazität beansprucht.

Jeff Atwood hat einen schönen Artikel über CodingHorror, der diese Einstellung erklärt; die kostengünstigste Lösung für ein Performance-Problem Hardware zu werfen (oder in diesem Fall erhöhte Speicherressourcen) auf dem Problem, bevor Sie investieren Entwickler Zeit bei der Fehlersuche:

http://www.codinghorror.com/blog/archives/001198.html

3

der Tat einen großen max Einstellung Wert blind ist nicht wirklich eine gute Idee (Maßnahme, nicht raten) und diese Strategie wird zu sehr langen "Stop-the-World" großen GCs führen, die aus Sicht der Benutzererfahrung nicht wünschenswert sein könnten (immer daran denken, dass " je größer der Haufen, desto länger der Haupt-GC ").

Das heißt, es gibt keine generische Antwort auf Ihre Frage, jede Anwendung hat andere Bedürfnisse. Eigentlich würde ich vorschlagen, Profil Ihre Anwendung und tune den Heap, um einen guten Kompromiss zwischen (Haupt) GC-Frequenz und (Haupt) GC-Dauer zu finden, während die Reaktionszeit für den Endbenutzer zu minimieren. Ich empfehle wärmstens, dieses großartige blog post (und alle anderen) von Kirk Pepperdine für weitere Details zu lesen.

Nur um den minimalen und maximalen Wert zu beantworten, verwende ich immer die gleichen Werte (für bessere Startleistung und bessere Reproduzierbarkeit).

+0

Das Problem ist, dass mein Anwendungs-Footprint von der Eingabe abhängt. Also Profiling ist irgendwie schwierig – LB40

+0

@LB in jeder gegebenen Anwendung (gleiche Codebasis) das Nutzungsprofil kann sehr unterschiedlich sein. Ich muss alle meine Kunden in Post-Go-Live-Situationen für das JVM-Tuning als Teil einer größeren Profilierungs- und Optimierungsphase beraten, da sie von Kunde zu Kunde und von Nutzer zu Nutzer wechselt. – Xailor

+0

Warum, ich verstehe es nicht? Wie sieht die Benutzereingabe für 80% der Benutzer aus? –

2

Es ist eine sehr schlechte Idee, den Parameter "-Xms" zu ignorieren, da in der Regel andere Anwendungen und Prozesse auf derselben Box ausgeführt werden. Sie möchten, dass Ihre Anwendung mit der maximalen Menge an zugewiesenem RAM gestartet wird. Wenn sie fehlschlägt, schlägt sie fehl, während Sie die Startup-Protokolle beobachten. Und nicht um 4:00 Uhr, wenn eine andere Anwendung zusätzlichen RAM auf der Box belegt hat. und Ihre JVM kann nicht in der Größe wachsen.

Kurz gesagt, IMMER JVM min einstellen und Größe mit dem gleichen Wert mischen.

Verwandte Themen