Non GC garantire che cancellato i Riferimenti sono accodato a ReferenceQueue in ordine topologico?

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

Domanda

Dico che ci sono due oggetti, A e B, e c'è un puntatore A.x --> B, e siamo noi a creare, diciamo, WeakReferences per entrambi A e B, con un associato ReferenceQueue.

Si supponga che sia A e B diventa irraggiungibile.Intuitivamente B non può essere considerato irraggiungibile prima A è.In tal caso, possiamo ottenere in qualche modo una garanzia che i rispettivi riferimenti saranno accodate alla intuitivo (topologica quando non ci sono cicli) ordine del ReferenceQueue?I. e.rif(A) prima del rif(B).Non so - cosa succede se il GC ha segnato una serie di oggetti come irraggiungibile, e quindi accodato in nessun ordine particolare?

Stavo rivedendo Finalizer.java di guava, vedendo questo frammento:

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 è un PhantomReference per l'usato ReferenceQueue, se è così GC autenticata, non Finalizzabili{Debole, Morbido, Phantom}Riferimenti possono essere vivo, dal momento che fanno riferimento a coda.Così devono essere GC sotto prima che la coda di per sé può essere GC sotto - ma ancora, non abbiamo la garanzia che questi riferimenti saranno accodati al ReferenceQueue alla fine vengono "garbage collection" (come se essi ottenere GC cantando uno per uno)?Il codice implica che ci sia un qualche tipo di garanzia, altrimenti non trasformati riferimenti teoricamente in grado di rimanere in coda.

Grazie

È stato utile?

Soluzione

Non v'è alcuna garanzia ordinamento. Nel caso di Finalizer.java, il filo può essere spento prima tutti i riferimenti vengono elaborati. Vedere la documentazione per FinalizableReferenceQueue:

  • Tenere un forte riferimento a questo oggetto fino a quando tutti gli associati

  • referenti sono stati finalizzati. Se questo oggetto è garbage collection in precedenza,
  • il filo di supporto non invocherà {@code finalizeReferent ()} sul
  • riferimenti rimanenti.

Questo è un comportamento intenzionale. Ad esempio, utilizziamo FRQ per ripulire voci della mappa in cui i riferimenti alle chiavi e / o valori vengono cancellati. Se l'utente non ha più un riferimento alla mappa, e, a sua volta non ha più un riferimento al FRQ, non c'è nessun punto nella lavorazione tali riferimenti.

Altri suggerimenti

Sono abbastanza sicuro che la risposta è no.

La specifica JVM dice sui metodi Finalizer:

  

La macchina virtuale Java impone nessun ordinamento sulle chiamate di metodo finalizzazione. Finalizzatori possono essere chiamati in qualsiasi ordine o simultaneamente. ( JVM spec 2.17.7 )

Da questo deduco che non ci sono garanzie che i riferimenti sono in coda in ordine topologico.

Penso che non ci sia tale garanzia.Il GC non ha in sé una completa ed immediata visualizzazione della RAM (non può, in quanto il GC viene eseguito sulla CPU, che può solo guardare un paio di byte alla volta).Nel tuo esempio, ipotizzando una base di "mark & sweep" GC, è probabile che A e B sarà dichiarato irraggiungibile nella stessa fase di segno di spunta, e spazzato insieme, in nessun ordine particolare.Il mantenimento di ordine topologico sarebbe probabilmente essere costoso.

Come per Finalizer, sembra che esso è destinato a essere utilizzato attraverso un FinalizableReferenceQueue solo l'istanza, che fa un po ' di classloader relative magia.Il Finalizer utilizza le proprie strutture per rilevare quando il FinalizableReferenceQueue da cui funzionalmente dipende diventa irraggiungibile;questo è il punto in cui il filo che scorre Finalizer sa che dovrebbe uscire.Da quello che ho capito, se l'applicazione consente il GC recuperare la FRQ, quindi il relativo thread verrà chiuso, e tutti i riferimenti accodato "dopo" la FRQ riferimento non saranno trattati.Questo dipende dall'ordine topologico o la mancanza di esso, ma non riesco a decidere se questo è un problema o meno.Penso che l'applicazione non dovrebbe cadere la sua FRQ come lungo come l'elaborazione di bonifica oggetti di riferimento è importante.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top