Unterschied zwischen "On-Heap" und "Off-Heap"


Antworten:


169

Der On-Heap-Speicher bezieht sich auf Objekte, die im Java-Heap vorhanden sind (und auch der GC unterliegen). Andererseits bezieht sich der Off-Heap-Speicher auf (serialisierte) Objekte, die von EHCache verwaltet werden, aber außerhalb des Heaps gespeichert sind (und auch nicht der GC unterliegen). Da der Off-Heap-Speicher weiterhin im Speicher verwaltet wird, ist er etwas langsamer als der On-Heap-Speicher, aber immer noch schneller als der Festplattenspeicher.

Die internen Details, die mit der Verwaltung und Verwendung des Off-Heap-Speichers verbunden sind, sind in dem in der Frage angegebenen Link nicht sehr offensichtlich. Es ist daher ratsam , die Details von Terracotta BigMemory zu überprüfen, das zum Verwalten des Off-Disk verwendet wird Geschäft. BigMemory (der Off-Heap-Speicher) soll verwendet werden, um den Overhead von GC auf einem Heap zu vermeiden, der mehrere Megabyte oder Gigabyte groß ist. BigMemory verwendet den Speicheradressraum des JVM-Prozesses über direkte ByteBuffer , die im Gegensatz zu anderen nativen Java-Objekten nicht der GC unterliegen.


18
+1 für die Erwähnung direkter ByteBuffers zur weiteren Erkundung;)
Max

3
Direkte ByteBuffer bieten Zugriff auf nicht verwalteten Speicher, unterliegen jedoch selbst der GC (im Gegensatz zu den Daten, auf die sie verweisen). Dies ist wichtig, da ein direkter ByteBuffer (die Art ByteBuffer.allocateDirect, nicht die Art MMap) vom GC erfasst wird. Wenn er erfasst wird, wird sein Deallocater ausgelöst, wodurch auch der nicht verwaltete Speicher effektiv erfasst wird.
Nitsan Wakart

Die Verwendung von Unsafe zum Zuweisen von Objekten scheint eine deutlich bessere Lese- und Schreibleistung gegenüber Onheap / DirectByteBuffers / ByteBuffers zu haben. ashkrit.blogspot.com/2013/07/…
Joe C

98

von http://code.google.com/p/fast-serialization/wiki/QuickStartHeapOff

Was ist Heap-Offloading?

Normalerweise werden alle nicht temporären Objekte, die Sie zuweisen, vom Java-Garbage Collector verwaltet. Obwohl die VM bei der Speicherbereinigung gute Arbeit leistet, muss die VM zu einem bestimmten Zeitpunkt einen sogenannten "Full GC" durchführen. Ein vollständiger GC umfasst das Scannen des vollständig zugewiesenen Heaps. Dies bedeutet, dass GC-Pausen / Verlangsamungen proportional zur Größe eines Anwendungsheaps sind. Vertraue also keiner Person, die dir sagt: "Gedächtnis ist billig". Im Java-Speicher beeinträchtigt der Verbrauch die Leistung. Außerdem können bei Heap-Größen> 1 GB bemerkenswerte Pausen auftreten. Dies kann unangenehm sein, wenn in Echtzeit Cluster ausgeführt werden. In einem Cluster oder Grid reagiert ein Java-Prozess möglicherweise nicht mehr und wird aus dem Cluster entfernt.

Heutige Serveranwendungen (die häufig auf aufgeblähten Frameworks basieren ;-)) erfordern jedoch leicht Heaps, die weit über 4 GB hinausgehen.

Eine Lösung für diese Speicheranforderungen besteht darin, Teile der Objekte auf den Nicht-Java-Heap (direkt vom Betriebssystem zugewiesen) zu verlagern. Glücklicherweise bietet java.nio Klassen zum direkten Zuweisen / Lesen und Schreiben von nicht verwalteten Speicherblöcken (sogar Dateien mit Speicherzuordnung).

Man kann also große Mengen an 'nicht verwaltetem' Speicher zuweisen und damit Objekte dort speichern. Um beliebige Objekte im nicht verwalteten Speicher zu speichern, ist die Verwendung der Serialisierung die sinnvollste Lösung. Dies bedeutet, dass die Anwendung Objekte in den Offheap-Speicher serialisiert. Später kann das Objekt mithilfe der Deserialisierung gelesen werden.

Die von der Java-VM verwaltete Heap-Größe kann klein gehalten werden, sodass die GC-Pausen im Millis liegen. Alle sind glücklich und haben ihre Arbeit erledigt.

Es ist klar, dass die Leistung eines solchen Off-Heap-Puffers hauptsächlich von der Leistung der Serialisierungsimplementierung abhängt. Gute Nachricht: Aus irgendeinem Grund ist die FST-Serialisierung ziemlich schnell :-).

Beispiel für Verwendungsszenarien:

  • Sitzungscache in einer Serveranwendung. Verwenden Sie eine Speicherzuordnungsdatei, um Gigabyte (inaktiver) Benutzersitzungen zu speichern. Sobald sich der Benutzer bei Ihrer Anwendung anmeldet, können Sie schnell auf benutzerbezogene Daten zugreifen, ohne sich mit einer Datenbank befassen zu müssen.
  • Zwischenspeichern von Berechnungsergebnissen (Abfragen, HTML-Seiten usw.) (gilt nur, wenn die Berechnung langsamer ist als das Deserialisieren des Ergebnisobjekts von c).
  • Sehr einfache und schnelle Persistenz mit speicherabgebildeten Dateien

Bearbeiten: In einigen Szenarien kann man komplexere Garbage Collection-Algorithmen wie ConcurrentMarkAndSweep oder G1 wählen, um größere Heaps zu unterstützen (dies hat jedoch auch seine Grenzen über 16 GB-Heaps hinaus). Es gibt auch eine kommerzielle JVM mit verbesserter "pausenloser" GC (Azul).


4
"reservieren Sie große Mengen an 'nicht verwaltetem' Speicher und verwenden Sie diesen, um Objekte dort zu speichern" - Sie können Objekte nicht außerhalb des Speichers speichern. Sie können Grundelemente speichern, Sie können sie in eine beliebige Bibliothek einschließen, aber dies sind keine Objekte. Die Daten, die Sie offheap platzieren, haben keinen Objektheader, Sie können nicht synchronisieren, Sie können nicht mit einem Referenzfeld in einem anderen Objekt darauf verweisen.
Nitsan Wakart

41

Der Heap ist der Ort im Speicher, an dem Ihre dynamisch zugewiesenen Objekte leben. Wenn Sie verwendet haben, newdann ist es auf dem Haufen. Dies steht im Gegensatz zum Stapelspeicher, in dem sich der Funktionsstapel befindet. Wenn Sie eine lokale Variable haben, befindet sich diese Referenz auf dem Stapel. Der Heap von Java unterliegt der Speicherbereinigung und die Objekte können direkt verwendet werden.

Der Off-Heap-Speicher von EHCache entfernt Ihr reguläres Objekt vom Heap, serialisiert es und speichert es als Bytes in einem von EHCache verwalteten Speicherblock. Es ist wie das Speichern auf der Festplatte, aber es befindet sich immer noch im RAM. Die Objekte sind in diesem Zustand nicht direkt verwendbar, sie müssen zuerst deserialisiert werden. Auch nicht der Müllabfuhr unterworfen.


Ist es nicht einfach noch auf dem Haufen, sondern als serialisierte Form?
Pacerier

1
Wie macht es das effizienter?
Pacerier

2
Es gibt viele Möglichkeiten. Da sich die Objekte nicht mehr auf dem Java-Hauptheap befinden, verschwenden sie nicht die Zeit des Garbage Collectors, fragmentieren den Heap der JVM nicht und geben Speicherplatz für andere häufig verwendete Objekte frei. Da sie serialisiert sind und wahrscheinlich in naher Zukunft nicht benötigt werden, können sie auch komprimiert, nach Bedarf verschoben oder sogar auf die Festplatte ausgelagert werden.
Adam

1
In Hotspot hängt die GC-Pausenzeit direkt von der Heap-Größe ab. BigMemory bietet diesen Kompromiss, indem RAM anstelle von Heap verwendet wird, um die GC-Pause auf ein Minimum zu beschränken und die E / A-Kosten für den Festplattenzugriff zu vermeiden.
Chander Shivdasani


1

Die JVM weiß nichts über Off-Heap-Speicher. Ehcache implementiert einen On-Disk-Cache sowie einen In-Memory-Cache.


1

Nicht 100%; Es hört sich jedoch so an, als wäre der Heap ein Objekt oder eine Menge zugewiesenen Speicherplatzes (im RAM), der in die Funktionalität des Codes integriert ist, entweder Java selbst oder wahrscheinlicher die Funktionalität von ehcache selbst, und der Off-Heap-Ram ist ein eigenes System als Gut; Es hört sich jedoch so an, als ob dies eine Größenordnung langsamer ist, da es nicht so organisiert ist, was bedeutet, dass möglicherweise kein Heap verwendet wird (was bedeutet, dass ein langer Satz RAM-Speicherplatz vorhanden ist) und stattdessen unterschiedliche Adressräume verwendet werden, was die Effizienz wahrscheinlich etwas verringert.

Die nächst niedrigere Stufe ist natürlich der Festplattenspeicher selbst.

Ich benutze keinen ehcache, deshalb möchten Sie mir vielleicht nicht vertrauen, aber das habe ich aus ihrer Dokumentation entnommen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.