Frage

Verschiebt die Java Virtual Machine jemals Objekte im Speicher, und wenn ja, wie geht sie mit der Aktualisierung von Verweisen auf das verschobene Objekt um?

Ich frage, weil ich eine Idee zur verteilten Speicherung von Objekten untersuche (d. h.über mehrere Server hinweg), aber ich benötige aus Effizienzgründen die Möglichkeit, Objekte zwischen Servern zu verschieben.Objekte müssen in der Lage sein, Zeiger aufeinander zu enthalten, auch auf Objekte auf Remote-Servern.Ich versuche, mir die beste Möglichkeit zu überlegen, Verweise auf verschobene Objekte zu aktualisieren.

Meine beiden Ideen sind bisher:

  1. Behalten Sie eine Referenzindirektion irgendwo bei, die sich während der Lebensdauer des Objekts nicht bewegt. Diese wird aktualisiert, wenn sich das Objekt bewegt.Aber wie werden diese Umwege verwaltet?
  2. Führen Sie zu jedem Objekt eine Liste mit Rückwärtsreferenzen, damit wir wissen, was aktualisiert werden muss, wenn das Objekt verschoben wird.Dies führt natürlich zu einem Leistungsaufwand.

Ich wäre an Feedback zu diesen Ansätzen und Vorschlägen für alternative Ansätze interessiert.

War es hilfreich?

Lösung

In Bezug auf den Kommentar oben über den Haufen zu Fuß.

Verschiedene GC tun es verschiedene Möglichkeiten.

Normalerweise Sammler kopieren, wenn sie den Haufen gehen, sie nicht alle Objekte in der Halde zu Fuß. Vielmehr gehen sie die LIVE-Objekte in der Halde. Die Implikation ist, dass, wenn sie von dem „root“ Objekt erreichbar sind, lebt das Objekt ist.

Also, in diesem Stadium hat, ist ohnehin all Live-Objekte zu berühren, da sie kopiert sie aus dem alten Haufen auf den neuen Haufen. Sobald die Kopie der Live-Objekte erfolgt ist, alles, was in der alten Halde bleibt sind entweder Objekte bereits kopiert oder Müll. An diesem Punkt kann der alte Haufen vollständig verworfen werden.

Die beiden wichtigsten Vorteile dieser Art von Sammler sind, dass sie den Haufen während der Kopierphase verdichtet, und dass es nur Kopien Objekte leben. Dies ist wichtig für viele Systeme, weil mit dieser Art von Kollektor, ist Objektzuordnung Schmutz billig, buchstäblich etwas mehr als einen Heapzeiger erhöht wird. Wenn GC passiert, keiner der „toten“ Objekte kopiert werden, so dass sie den Sammler nicht verlangsamen. Es stellt sich auch in dynamischen Systemen heraus, dass es noch viel mehr kleiner, temporärer Müll, als es seit langer Müll ist.

Auch durch das Live-Objektgraphen zu Fuß, können Sie sehen, wie der GC kann „wissen“ über jedes Objekt, und behält sie für jede Adresse Justagezwecken während der Kopie durchgeführt.

Dies ist nicht das Forum tief über GC Mechanik zu sprechen, da es ein nicht-triviales Problem ist, aber das ist die Grundlagen, wie ein Kopier Kollektor arbeitet.

Ein Generation Kopieren GC wird gesetzt „ältere“ Objekte in verschiedenen Haufen, und die am Ende weniger häufig gesammelt als „neuere“ Haufen. Die Theorie ist, dass die lang anhaltenden Objekte zu älteren Generationen gefördert bekommen und bekommen immer weniger gesammelt, insgesamt GC Leistung verbessert wird.

Andere Tipps

(praktisch) Jeder Müll gesammelt System hat Objekte um im Speicher zu bewegen, sie dichter zu packen und Fragmentierungsprobleme zu vermeiden.

Was Sie sehen, ist ein sehr großes und komplexes Thema. Ich würde Sie auf vorhandene Remote-Objektstil API nachlesen vorschlagen: .NET Remoting und geht weiter zurück Technologien wie CORBA

Jede Lösung, die Referenzen für die Verfolgung wird, indem kompliziert sein mit allen Fehlerarten beschäftigen, die in verteilten Systemen existieren. Die JVM muss nicht über plötzlich Sorgen finden es nicht die Hälfte seines Haufen sehen können, weil ein Netzwerk-Switch glitched.

Wenn Sie in das Design bohren Ich denke, eine Menge davon kommt darauf an, wie man verschiedene Fehlerfälle behandelt werden sollen.

Reaktion auf die Kommentare:

Ihre Frage spricht über Objekte in einer verteilten Art und Weise zu speichern, das ist genau das, was .NET Remoting und CORBA-Adresse. Zwar unterstützt weder Technologie Migration dieser Objekte (AFAIK). Aber sie beide viel umfangreich mit den Konzepten der Objektidentität, die ein wichtiger Bestandteil jeder verteilten Objektsystems ist. Wie andere Teile des Systems wissen, welche Objekte sie reden

Ich bin nicht übermäßig mit den Details der Java Garbage Collector vertraut, und ich bin sicher, die Java- und .NET-Müllsammler in ihnen viel Komplexität haben über die Anwendung maximale Leistung bei minimalem Wirkung zu erzielen.

Allerdings ist die Grundidee für die Garbage Collection ist:

  • Die VM stoppt alle Threads ausgeführt verwalteten Code
  • Es führt eine Erreichbarkeitsanalyse aus der Menge der bekannten ‚Wurzeln‘: statische Variablen, lokale Variablen auf allen Threads. Für jedes Objekt es findet es alle Verweise innerhalb des Objekts folgt.
  • Jedes Objekt durch die Erreichbarkeitsanalyse nicht identifiziert ist Müll.
  • Objekte, die noch am Leben sind, können dann nach unten im Speicher verschoben werden, um sie dicht zu packen. Dies bedeutet, dass alle Verweise auf diese Objekte auch mit der neuen Adresse aktualisiert werden müssen. Durch die Steuerung, wenn ein Abfall sammeln kann die VM kann garantieren, auftritt, dass es keine Objektreferenzen ‚in-the-Air‘ (dh. In einem Maschinenregister gehalten wird), die ein Problem verursachen würde.
  • Sobald der Prozess abgeschlossen die VM startet die Fäden Ausführung wieder.

Als Verfeinerung dieses Prozesses kann die VM Generations-Speicherbereinigungsdurchführen, wo getrennte Haufen basierend auf dem ‚Alter‘ ein Objekt beibehalten werden. Objekte beginnen in Haufen 0 und wenn sie mehrere GCs dann der Migrate überleben 1 häufen und schließlich 2 zu häufen (und so weiter - .NET unterstützt drei Generationen nur obwohl). Der Vorteil hierbei ist, dass der GC kann sehr häufig Haufen 0 Sammlungen laufen, und müssen sich keine Sorgen über die Arbeit zu tun, die lange gelebt Objekte sind noch am Leben (was in Haufen 2 endete haben) zu beweisen (was sie mit ziemlicher Sicherheit sind) .

Es gibt noch weitere Verfeinerungen gleichzeitige Garbage Collection, und Details rund um Threads zu unterstützen, die nicht verwalteten Code tatsächlich ausgeführt werden, wenn der GC geplant ist, die viel mehr Komplexität in diesem Bereich hinzuzufügen.

Ich würde gerne mehr über Ihre Anforderungen erfahren.Wie aus einer anderen Antwort hervorgeht, könnte Terrakotta genau das sein, wonach Sie suchen.

Es gibt jedoch einen subtilen Unterschied zwischen dem, was Terrakotta bietet, und dem, was Sie verlangen, daher meine Anfrage.

Der Unterschied besteht darin, dass Terracotta Ihrer Meinung nach keine „entfernten“ Verweise auf Objekte bereitstellt – tatsächlich die gesamte „entfernte“ Vorstellung von RMI, JMS usw.fehlt bei der Verwendung von Terrakotta gänzlich.

Vielmehr befinden sich in Terrakotta alle Objekte auf einem großen virtuellen Haufen.Threads, ob auf Knoten 1 oder Knoten 2, Knoten 3, Knoten 4 usw., haben alle Zugriff auf jedes Objekt im virtuellen Heap.

Es müssen keine spezielle Programmierung oder spezielle APIs erlernt werden. Objekte im „virtuellen“ Heap verhalten sich genau wie Objekte im lokalen Heap.

Kurz gesagt: Was Terracotta bereitstellt, ist ein Programmiermodell für mehrere JVMs, das genauso funktioniert wie das Programmiermodell für eine einzelne JVM.Threads in separaten Knoten verhalten sich einfach wie Threads in einem einzelnen Knoten – Objektmutationen, synchronisiert, warten, benachrichtigen – alle verhalten sich über Knoten hinweg genauso wie über Threads hinweg – es gibt keinen Unterschied.

Darüber hinaus werden Objektreferenzen, anders als bei anderen Lösungen zuvor, knotenübergreifend verwaltet – das heißt, Sie können == verwenden.Dies alles ist Teil der Aufrechterhaltung des Java-Speichermodells im gesamten Cluster, was die Grundvoraussetzung für die Erstellung von „normalem“ Java (z. B.POJOs, synchronisiert, warten/benachrichtigen) funktionieren (nichts davon funktioniert, wenn Sie die Objektidentität nicht im gesamten Cluster beibehalten können).

Daher stellt sich Ihnen die Frage, wie Sie Ihre Anforderungen weiter verfeinern können: Für welchen Zweck benötigen Sie „entfernte“ Zeiger?

Das Schlüsselwort Sie nach ist „Garbage Collector Verdichten“. JVMs erlaubt eine verwenden, was bedeutet, dass Objekte verschoben werden kann. Wenden Sie sich JVM Anleitung, um herauszufinden, ob Ihr tut, und zu sehen, ob es irgendwelche Befehlszeilenoptionen sind, die sie betreffen.

Die konzeptionell einfachste Art und Weise Verdichtung zu erklären, ist anzunehmen, dass der Garbage Collector alle Themen friert, zieht das Objekt, sucht Heap und Stack für alle Verweise auf das Objekt, und aktualisiert sie mit der neuen Adresse. Eigentlich ist es komplizierter als das, da aus Performance-Gründen Sie keine vollständige Sweep mit Threads blockiert ausführen wollen, so eine inkrementelle Garbage Collector tun Arbeit in der Vorbereitung für die Verdichtung, wann immer es kann.

Wenn Sie in indirekten Verweis interessiert sind, Sie durch die Erforschung schwach und weich Referenzen in Java, und auch die Remote-Referenzen, die von verschiedenen RPC-Systemen beginnen könnten.

klingt wie Sie für einen verteilten Cache, so etwas wie Terrakotta oder Oracles Java objece Cache (früher tangersol) suchen.

Wenn Sie bereit sind zu gehen, dass tief unten, Sie einen Blick auf JBoss Cache-Architektur-Dokumentation nehmen und einige seiner Quellcodes als Referenz greifen.

Dies ist nicht genau das, was Sie beschrieben, aber es funktioniert sehr ähnlich.

Hier ist der Link.

http://www.jboss.org/jbosscache/

Ich hoffe, das hilft.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top