4 Stimmen

Memory-Mapped Files und transparente Persistenz von Java-Objekten

Gruß an alle,

Ich möchte eine transparente Persistenz von Java-Objekten durch Memory-Mapped-Dateien erreichen (unter Verwendung des OS-Paging/Swapping-Mechanismus).

Mein Problem ist: Wie kann ich ein Java-Objekt in meinen memory-mapped Block verschieben? Und wie kann ich eine neue Objektinstanz dazu zwingen, in einem solchen Block zu residieren?

Wie Sie alle wissen, kann ein Memory-Mapped-Block als Byte-Array angesehen werden, und was ich hier wirklich frage, ist, wie man den Adressraum von Java-Objekten mit dem von solchen Arrays überlappen kann? So dass wir die Daten immer noch über Objekte manipulieren können, während das Betriebssystem die Persistenz transparent handhabt (schreibt schmutzige Seiten).

Wenn Java mir dies nicht erlaubt, welche plattformübergreifende und Müll sammelnde OO-Sprache würden Sie mir empfehlen?

Ich danke Ihnen allen im Voraus.

0 Stimmen

Bitte, was ist Ihr Speicher gemappt Datei aus einer Java-Perspektive? Ist es eine Datei, oder ein MappedByteBuffer oder etwas anderes? Vielen Dank!

0 Stimmen

Bisher verwende ich einen MappedByteBuffer, aber ich bin bereit, etwas anderes zu verwenden, wenn es mir helfen wird, transparent persistent über Paging/Swapping zu erreichen, während noch in der Lage, meine Objekte als Objekte und nicht nur Rohdaten in einem Byte-Array zu verwenden

0 Stimmen

Ich habe herausgefunden, dass das Problem in Java dadurch verkompliziert wird, dass der Garbage Collector beim Finalisieren von Objekten eine speicherinterne Defragmentierung vornimmt.

3voto

Gamlor Punkte 12588

Dies ist afaik nicht möglich. Und es gibt mehrere gute Gründe, warum die Laufzeitumgebung dies nicht zulässt.

  • Das Speicherlayout Ihres Objekts ist Teil der JVM-Interna. Jede JVM kann selbst entscheiden, wie sie Objekte anordnet. Dieses Layout kann sich mit jeder neuen Version ändern. Wenn Sie ein Objekt im Speicher auf eine Datei abbilden, würden Sie in Schwierigkeiten geraten. Was passiert, wenn sich das Objekt-Layout geändert hat? Absturz, Aktualisierung der Datei, Zauberei? Letztendlich würde das Memory-Mapping von Objekten in Dateien die Festlegung eines festen Objekt-Layouts erfordern.
  • Was passiert, wenn man ein Feld hinzufügt/entfernt? Dann hat sich das Objekt-Layout mit Sicherheit geändert. Sie können eine Datei nicht mit dem alten Speicher-Layout zuordnen.
  • Ein Objekt hat auch zusätzliche Informationen, wie die VTable für virtuelle Funktionsaufrufe, Felder für Sperrzustände usw. Wollen Sie diese auch abbilden? Wahrscheinlich nicht, denn das sind interne Laufzeitzustände. Man müsste also immer ein paar Bytes ignorieren oder Objekte aufteilen. Das würde das Speicher-Layout extrem komplex machen.
  • Der Garbage Collector verdichtet den Speicher, um die Fragmentierung durch Verschieben von Objekten zu minimieren. Daher muss es einen 'Fixierungs'-Mechanismus für Objekte geben. (das ist in .NET möglich, aus Interop-Gründen)
  • Der Garbage Collector arbeitet in Generationen. Ein Objekt wird zunächst einer jungen Generation zugeordnet. Wenn es überlebt, wird es in eine andere Generation verschoben. Ein Objekt, das dem Speicher zugeordnet ist, würde eine Ausnahme erfordern.

Aus all diesen Gründen kann man Java/.NET-Objekte nicht im Speicher abbilden. Die Unterstützung einer solchen Funktion würde die JVM/CLR extrem komplex machen.

Die JVM/CLR gibt Ihnen immer noch Zugriff auf Memory-Mapped-Dateien als Array-ähnliche Abstraktion, in die Sie Bytes schreiben/lesen können. Darüber hinaus können Sie Ihren Persistenz-Mechanismus implementieren. Von einfacher Serialisierung bis hin zu komplexen Datenbanken. Es gibt Objektdatenbanken, die einer transparenten Persistenz recht nahe kommen. Dann verhalten sich Objekte wie persistente Datenstrukturen / memory-mapped objects.

0 Stimmen

Was meinen Sie mit "außer Kraft setzen"? Natürlich ist es möglich, eine andere GC zu schreiben und diese in die JVM/CLR zu integrieren. Und beide bringen unterschiedliche GC mit sich. Aber es ist sicherlich nicht einfach, einen effizienten Garbage Collector zu schreiben. Außerdem arbeitet ein effizienter GC mit den anderen Teilen der Laufzeitumgebung zusammen. Zum Beispiel mit dem JIT-Compiler (Hinzufügen von Schreibbarrieren).

3voto

Carl Rosenberger Punkte 890

Die einzige Möglichkeit, dies zu tun, besteht darin, eine eigene Java-VM zu verwenden und diese Funktionalität hinzuzufügen. Natürlich wäre der Code, den Sie schreiben würden, nicht in Java, sondern in der Sprache, in der die VM implementiert ist. Vor einiger Zeit hat Gemstone diesen Ansatz für seine Objektdatenbank-Engine verwendet.

Heutige Objektdatenbanken (ich arbeite an einer) arbeiten nicht auf diese Weise. Es ist viel einfacher, den Bytecode zu verbessern, um den Feldzugriff zu verfolgen und Reflection oder injizierte Methoden zu verwenden, um Objekte in eine Art serialisierte Form zu bringen. Das funktioniert recht gut. Wenn Sie Abfragen unterstützen wollen, müssen Sie ohnehin mit einzelnen Feldwerten arbeiten, um sie zu indizieren.

Für uns wäre es einfach nicht machbar, eine VM für alle Plattformen, auf denen wir arbeiten wollen, zu unterhalten. Wir könnten auch keine ernsthaften Kunden davon überzeugen, ihre gesamte (Bank-)Anwendung auf eine von uns angepasste VM zu setzen.

Wenn Sie ernsthaft daran interessiert sind, eine Lösung auf der Grundlage einer Java VM zu entwickeln: Es gab mal ein interessantes Java-Forschungsprojekt für orthogonale transparente Persistenz namens "Forest". Vielleicht finden Sie alte Unterlagen oder sogar Quellcode.

Wenn Sie nach einer anderen Sprache suchen, um "Objekte" direkt aus dem Speicher zu übernehmen: Mit C++ können Sie das tun. Es gibt einige alte, in C++ geschriebene Objektdatenbanken, die diesen Ansatz verwenden. ...aber hey, das ist doch verrückt, Seitenfehler zum Laden von Objekten zu verwenden. Diese Art von Objektdatenbanken haben das schlechte Image erzeugt. Ich hoffe, dass wir das bald wieder ändern werden.

1voto

meriton Punkte 65030

Das können Sie nicht.

Java erzwingt von Haus aus Typsicherheit und referenzielle Integrität. Das heißt, wenn ich ein Feld des Referenztyps T habe, weiß ich, dass es auf eine Instanz von T zeigt (abgesehen von der Heap-Verschmutzung durch Typlöschung). Dies steht im Gegensatz zu "unsicheren" Sprachen wie C++, bei denen es durchaus möglich ist, dass ein Verweis auf eine ungültige Stelle zeigt, wo dieser Verweis eine "Speicherbeschädigung" verursachen kann.

Wenn Java erlaubt, ein Byte[] als Object kann sie die referenzielle Integrität nicht garantieren.

0 Stimmen

Warum können wir nicht wie MemoryMap<T> von einigen Klasse-Typ anstelle der Festsetzung es für Bytes haben?

0 Stimmen

Da die Datei, die Sie dem Speicher zuordnen, nicht notwendigerweise konsistent ist, müsste Java dies beim Laden der Datei überprüfen. Und was ist mit Verweisen auf Daten außerhalb der im Speicher abgebildeten Region? Jedes Java-Objekt behält einen Verweis auf sein Klassenobjekt, das wiederum seinen Classloader kennt, der wiederum weiß, wo sich die Klassen im Dateisystem befinden ...

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