Die Java Virtual Machine organisiert und verwaltet die Objekte einer Anwendung selbst im so genannten Heap-Speicher. Diese wurde im Beitrag über Referenzen und Objekte beschrieben. Ein automatischer Hintergrundprozess, die Garbage Collection, entfernt automatisch nicht mehr referenzierbare Objekte und bereinigt somit den Speicher.
“Native Memory” bzw Off-Heap Memory in Java ist jedoch ebenfalls möglich!
Was ist “Off-Heap Memory”?
Das Off-Heap Memory ist, wie der Name auch sagt, außerhalb der des Heaps angesiedelt und wird deshalb nicht von der Garbage Collection bereinigt. Weiterhin ist es für einen Programmierer nicht möglich, Objekte direkt im Off-Heap Memory zu instanzieren. Damit ist die Benutzung deutlich komplexer und auch mit mehr Fehlerpotenzial behaftet als das Referenzen-Modell.
Warum “Off-Heap Memory”?
Damit scheint die Benutzung dieses Speichers ein Rückschritt zu sein: Der Programmierer hat deutlich mehr Verantwortung, nicht mehr notwendige Daten zu identifizieren und dann auch selber zu löschen. Weiterhin müssen auch alle abhängigen Objekte erkannt werden. Es stellt sich deshalb die Frage, was denn Szenarien sein könnten, dieses native Memory zu benutzen.
Dafür kann aber sofort ein eingängiges Beispiel gefunden werden: Ein Java-basierter Cache!
Zur Ablage der Cache-Einträge ist das Native Memory nämlich wunderbar geeignet:
- Die Gültigkeit von Daten, die im Cache abgelegt werden, ist mit Stunden oder sogar noch viel länger aus Sicht der Frequenz der Garbage-Collection wirklich sehr lange. Damit prüft der Collector diese Objekte immer wieder darauf, ob sie nun endlich gelöscht werden können. Eine sinnlose und damit ineffiziente Verschwendung von CPU-Ressourcen.
- Cache-Daten sind häufig eher flache Datenstrukturen und nicht komplexe Objektgrafen.
- Der Lebenszyklus der Daten ist simpel: Mit
put
werden die Daten geschrieben, mitget
gelesen und mitremove
gelöscht. Eine einfach zu programmierende Sequenz.
In zwei anderen Artikeln wird das Off-Heap-Memory mit Java-Beispiele genutzt: Einmal mit der internen Klasse Unsafe und dann mit den Buffern des NIO.