Ein Java-Prozess besteht grundsätzlich aus zwei verschiedenen Heap-Spaces.
- Der Java-Heap (neuer, alter und permanenter Speicherplatz)
- Und der sogenannte native C-Heap.
Das Obige ist oft verwirrend, wenn es um OutOfMemory-Fehler und Zuordnungsfehler geht. Insbesondere im 32-Bit-Modus, wo der gesamte Prozessspeicher je nach Betriebssystem auf 4 GB oder sogar 2 GB begrenzt ist.
Wie bereits erwähnt, ist die Gesamtprozessgröße im 32-Bit-Modus auf maximal 4 GB begrenzt. Java-Heap und C-Heap kombiniert, zusammen mit anderen Leerzeichen, z. für Bibliotheken, Threads usw. darf diese 4-GB-Grenze nicht überschreiten. Wenn Sie also den Java-Heap erhöhen, z. Durch Erhöhen von -Xmx/-Xms von 1,5 GB auf 2,5 GB hat dies einen erheblichen Nebeneffekt auf dem C-Heap. Vor der Erhöhung konnte der C-Heap leicht auf bis zu 2 GB anwachsen. Da waren noch 4gb -1,5gb =2,5gb übrig. NACH der Erhöhung des Java-Heaps von 1,5 GB auf 2,5 GB bleiben nur noch 4 GB – 2,5 GB =1,5 GB für alle anderen Speicherplätze übrig. Einschließlich des C-Haufens.
Leider ist es völlig anwendungsabhängig, wie groß der Java-Heap und der C-Heap sein müssen. Während die Größe des Java-Heaps explizit konfiguriert werden kann, ist dies für den C-Heap nicht möglich. C-Heap wird einfach erweitert, bis die Prozessgröße die Grenze von 4 GB erreicht. Seien Sie also vorsichtig, wenn Sie den Java-Heap zu groß konfigurieren. Dies kann und wird zu Zuordnungsfehlern des C-Heap führen. Z.B. Meldungen wie diese bedeuten typischerweise, dass der C-Heap erschöpft ist:
java.lang.OutOfMemoryError: requested 67108872 bytes for Chunk::new. Out of swap space?
Bitte beachten Sie die C++-Syntax mit den doppelten Doppelpunkten. Oder dieses hier:
# There is insufficient memory for the Java Runtime Environment to continue. # Native memory allocation (malloc) failed to allocate 65544 bytes
In beiden Fällen war C-Heap zu klein. Eine Lösung wäre gewesen, den Java-Heap zu verkleinern. Ja, abnehmen! Dies hätte dem C-Haufen mehr Platz zum Ausdehnen gegeben. Auf der anderen Seite können wir immer noch auf die klassischen Java.lang.OutOfMemoryErrors treffen. Diese weisen eindeutig auf eine unzureichende Java-Heap-Kapazität hin.
Wie Sie sehen können, kann es im 32-Bit-Modus zu einem Konflikt zwischen Java und C-Heap kommen, der möglicherweise nicht einfach zu lösen ist. Wenn alles fehlschlägt, ziehen Sie in Betracht, auf 64-Bit umzusteigen, wo die Prozessgrößenbeschränkung von 4 GB kein Problem mehr darstellt. Hintergrundinformationen:Die Hotspot Java Virtual Machine (JVM) selbst ist in C++ geschrieben. Daher finden alle JVM-internen Zuweisungen ausschließlich im C-Heap statt. Wenn der GC zum Beispiel eingreift, um tote Objekte im Java-Heap zu sammeln, weist er Speicherplatz im nativen Heap zu, um seine Arbeit auszuführen.
Andererseits landen alle Java-Objekte, die von einem Java-Programm zugewiesen werden, im Java-Heap. Der C-Heap wird nicht berührt.