Hat GC garantieren, dass gelöscht Referenzen werden in die Warteschlange eingereiht, um ReferenceQueue in topologischer Reihenfolge?

StackOverflow https://stackoverflow.com/questions/2497014

Frage

Sagen, es gibt zwei Objekte, A und B, und es gibt einen Zeiger A.x --> B, und wir sagen, WeakReferences beide A und B, mit einem dazugehörigen ReferenceQueue.

Angenommen, dass beide A und B unerreichbar werden.Intuitiv B nicht als unerreichbar vor A ist.In solchen Fall, wir irgendwie erhalten Sie eine Garantie, dass die entsprechenden Verweise werden in die Warteschlange eingereiht in die intuitive (topologische wenn es keine Zyklen), um in den ReferenceQueue?I. e.ref(A), bevor Sie ref(B).Ich weiß nicht - was ist, wenn der GC markiert eine Reihe von Objekten, die als nicht erreichbar, und dann in die Warteschlange eingereiht, Sie in keiner bestimmten Reihenfolge?

Ich war die überprüfung Finalizer.java von Guave, sehen Sie dieses snippet:

private void cleanUp(Reference<?> reference) throws ShutDown {
  ...
  if (reference == frqReference) {
    /*
     * The client no longer has a reference to the
     * FinalizableReferenceQueue. We can stop.
     */
    throw new ShutDown();
  }

frqReference ist eine PhantomReference zu den verwendeten ReferenceQueue, also wenn das so ist GC ' ed, nicht Beendbar{Schwach, Weich, Phantom}Referenzen können lebendig sein, da Sie verweisen auf die Warteschlange.Sie haben also werden GC 'ed, bevor die Warteschlange selbst kann GC' ed, aber trotzdem bekommen wir die Garantie, dass diese Referenzen werden in die Warteschlange eingereiht, um die ReferenceQueue bei der Bestellung können Sie "garbage Collection" (als wenn Sie GC ' ed eins nach dem anderen)?Der code bedeutet, dass es irgendeine Art von Garantie, sonst unverarbeitet Referenzen könnten theoretisch in der Warteschlange verbleiben.

Vielen Dank

War es hilfreich?

Lösung

Es gibt keine Bestellgarantie. Im Fall von Finalizer.java kann der Faden heruntergefahren wird, bevor alle Verweise verarbeitet werden. Lesen Sie die Dokumentation für FinalizableReferenceQueue:

  • Halten Sie eine starke Referenz auf dieses Objekt, bis alle zugehörigen

  • referents finalisiert wurden. Wird dieses Objekt Müll früher gesammelt,
  • der Träger Thread wird nicht invoke {@code finalizeReferent ()} auf dem
  • verbleibenden Referenzen.

Dies ist ein vorsätzliches Verhalten. Zum Beispiel verwenden wir FRQ Map-Einträge zu bereinigen, wenn Verweisen auf die Tasten und / oder Werte gelöscht werden. Wenn der Benutzer nicht mehr einen Verweis auf die Karte hat, und wiederum nicht mehr einen Verweis auf die FRQ, es hat keinen Sinn, diese Referenzen in der Verarbeitung.

Andere Tipps

Ich bin mir ziemlich sicher, dass die Antwort nein ist.

Die JVM-Spezifikation sagt über Finalizerthread Methoden:

  

Die Java Virtual Machine erlegt keine Ordnung auf Finalisierung Methodenaufrufe. Finalizers können in beliebiger Reihenfolge oder sogar gleichzeitig aufgerufen werden. ( JVM-Spezifikation 2.17.7 )

Von diesem entnehme ich, dass es keine Garantien gibt, dass Verweise in topologische Ordnung Warteschlange gestellt werden.

Ich denke, es gibt keine solche Garantie.Die GC selbst nicht haben eine komplette und unmittelbare Sicht auf die RAM (kann es nicht, da der GC läuft auf der CPU, die können nur einen Blick auf ein paar bytes in einem-Zeit).In Ihrem Beispiel, unter der Annahme einer grundlegenden "mark & sweep" GC, sind die Chancen, dass A und B erklärt werden, nicht erreichbar in der gleichen Markierung phase, und kehrten gemeinsam in keiner bestimmten Reihenfolge.Die Aufrechterhaltung der topologischen Ordnung würde wahrscheinlich teuer werden.

Für Finalizer, es scheint, dass es sollte verwendet werden durch eine FinalizableReferenceQueue Instanz nur, die hat einige classloader-related Magie.Die Finalizer verwendet seine eigenen Einrichtungen zu erkennen, wenn die FinalizableReferenceQueue aus, die es funktional abhängt, wird selbst nicht erreichbar;dies ist der Punkt, wenn der thread läuft Finalizer weiß, dass es verlassen.Von dem, was ich verstehe, wenn die Anwendung ermöglicht die GC-reclaim-the-FRQ, dann wird der finalizer-thread wird beendet, und alle Verweise in die Warteschlange eingereiht "nach" der FRQ-Referenz wird nicht verarbeitet werden.Dies hängt davon ab, topologische Ordnung-oder das fehlen davon, aber ich kann mich nicht entscheiden, ob dies ein problem ist oder nicht.Ich denke, dass die Anwendung soll nicht Tropfen seiner FRQ so lange, wie die Verarbeitung von zurückgefordert Objekte verwiesen wird, ist wichtig.

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