4 Stimmen

Java-Speicherverbrauch mit nativen Prozessen

Wie lässt sich eine in Java geschriebene Serveranwendung, die eine native C++-Bibliothek verwendet, am besten optimieren?

Die Umgebung ist ein 32-Bit-Windows-Rechner mit 4 GB RAM. Das JDK ist Sun 1.5.0_12.

Dem Java-Prozess werden beim Start 1024 MB Speicher (-Xmx) zugewiesen, aber ich erhalte oft OutOfMemoryErrors wegen fehlendem Heap-Speicher. Wenn der Speicher auf 1200 MB erhöht wird, treten die OutOfMemoryErrors aufgrund von fehlendem Swap-Speicher auf. Wie wird der Speicher zwischen der JVM und dem nativen Prozess aufgeteilt?

Hat der Windows-Schalter /3GB irgendeine Auswirkung auf native Prozesse und Sun JVM?

2voto

gvlx Punkte 648

Ich hatte viele Probleme mit dieser Einstellung (Java auf 32-Bit-Systemen - msw und andere) und sie wurden alle gelöst, indem ich der JVM knapp *unter 1 GB RAM reservierte.

Andernfalls würde, wie bereits erwähnt, der tatsächlich belegte Speicher im System für diesen Prozess über 2 GB betragen; zu diesem Zeitpunkt hatte ich "stille Tode" des Prozesses - keine Fehler, keine Warnungen, nur das sehr leise Beenden des Prozesses.

Ich habe mehr Stabilität und Leistung, wenn ich mehrere JVMs (jede mit weniger als 1 GB RAM) auf demselben System laufen lasse.

1voto

Charlie Punkte 644

Ich fand einige Informationen auf JNI-Speicherverwaltung hier und hier ist die JVM JNI Abschnitt über die Speicherverwaltung .

Nun, 3 GB Benutzerplatz über 2 GB Benutzerplatz zu haben, sollte helfen, aber wenn Sie Probleme haben, wenn Ihnen bei 2 GB der Swap-Speicherplatz ausgeht, denke ich, dass 3 GB es nur noch schlimmer machen werden. Wie groß ist Ihre Auslagerungsdatei? Ist sie voll ausgelastet?

Sie können eine bessere Vorstellung von der Heap-Allokation bekommen, indem Sie jconsole an Ihren jvm anschließen.

0voto

ephemient Punkte 189038

Wie wird der Speicher zwischen der JVM und dem nativen Prozess aufgeteilt?

Der Garbage Collector der JVM von Sun ist ein Mark-and-Sweep-System mit Optionen für gleichzeitige und inkrementelle GC.

Nun, genauer gesagt, es ist inszeniert, und das oben Gesagte gilt nur für dauerhafte (langlebige) Objekte. Für junge Objekte wird GC immer noch mit einem Stop-and-Copy-Collector durchgeführt, der viel besser für die Arbeit mit kurzlebigen Objekten geeignet ist (und alle typischen Java-Programme erzeugen viele kurzlebige Objekte).

Ein Kopiersammler geht über alle Elemente im Heap, kopiert sie in einen neuen Heap, wenn sie referenziert sind, und verwirft dann den alten Heap. 1 Mio. lebende Objekte benötigen also bis zu 2 Mio. realen Speicher: Wenn jedes Objekt lebendig ist, gibt es während der Garbage Collection zwei Kopien von allem.

Die JVM benötigt also weit mehr Systemspeicher, als dem in der VM ausgeführten Code zur Verfügung steht, da ein erheblicher Overhead bei der Verwaltung und der Garbage Collection entsteht.

Hat der Windows-Schalter /3GB irgendeine Auswirkung auf native Prozesse und Sun JVM?

El /3GB erlaubt es, dass der Adressraum des virtuellen Benutzerspeichers 3 GB beträgt, aber nur für ausführbare Dateien, deren Header mit IMAGE_FILE_LARGE_ADDRESS_AWARE . Soweit ich weiß, ist Sun's java.exe ist nicht. Ich habe kein Windows-System hier, kann das also nicht überprüfen.

0voto

vy32 Punkte 26016

Sie haben Ihr Problem leider nicht gut genug erklärt. Die eigentliche Frage ist: Warum wächst der Java-Prozess so stark? Haben Sie ein Speicherleck? Gibt es einen wirklichen Grund, so viele Daten in der JVM zu haben?

Weist die C++-Bibliothek ihren eigenen Speicher aus dem C-Stack zu, oder weist sie Speicher aus dem Java-Objektraum zu, oder tut sie etwas ganz anderes?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X