Come eseguire il debug dei riferimenti deboli? [chiuso]

0

Come posso testare (quali strumenti devo usare) se il mio grafico di riferimento è corretto e se gli oggetti vengono rilasciati ai tempi appropriati (e non ci sono perdite di memoria)?

Nel mio caso sto usando Java, ma anche le risposte relative ad altre lingue sono benvenute ...

    
posta mrpyo 12.05.2014 - 16:28
fonte

2 risposte

1

Riferimenti deboli e la classe Reference in generale può essere controllato per la sua raggiungibilità chiamando isEnqueued() . Questo essenzialmente sta chiedendo se è pianificato di essere rimosso dal garbage collector (e quindi l'oggetto a cui WeakReference punta sta per essere annullato dal modo in cui WeakReference funziona).

Tuttavia, questo non garantisce che sarete in grado di "catturare" un oggetto prima che venga rimosso dal garbage collector. Può essere che un momento il suo riferimento sia utilizzato in un'altra classe e il prossimo, quella stessa istanza è già uscita dal campo di applicazione e da allora è stata rimossa dal garbage collector.

Un approccio alternativo potrebbe essere quello di mantenere un elenco di riferimenti (normali) alle istanze. Quando si desidera vedere se è l'unico riferimento rimasto, creare un WeakReference di tale istanza e quindi impostare il riferimento normale su null. Se è l'unico riferimento rimasto, allora isEnqueued() del WeakReference di quell'istanza dovrebbe restituire immediatamente true. Tecnicamente, il garbage collector può essere eseguito in qualsiasi momento, anche dopo la stessa riga in cui si imposta l'istanza normale su null, tuttavia è estremamente improbabile. Probabilmente potresti forzare il garbage collector a funzionare prima se vuoi ridurre ulteriormente questa possibilità.

L'unico svantaggio di questo approccio è, sì, sei potenzialmente in possesso di una serie di riferimenti a oggetti che altrimenti verrebbero eliminati. Sebbene tu possa rimediare a questo tenendo un elenco di riferimenti di SoftReference a queste istanze, che è essenzialmente come un WeakReference tranne per il fatto che non lascerà andare il riferimento a meno che tu non abbia assolutamente bisogno di più memoria.

In questo modo, puoi essere sicuro che questa classe non interferirà con la pulizia, eppure puoi ancora tenere traccia di se un'istanza verrebbe eliminata o meno. Dopo aver gestito l'evento, tuttavia, dovresti fare la cosa responsabile e rimuovere successivamente il tuo SoftReference , consentendo in tal modo alla tua istanza di essere liberata per il roaming dei Campi Elisi.

Spero che questo aiuti. Fammi sapere se questo ha risposto alla tua domanda.

    
risposta data 12.05.2014 - 18:15
fonte
1

Se il tuo obiettivo è solo quello di tenere un registro di quando gli oggetti non vengono più utilizzati, guarderei ReferenceQueue , che dovrebbe essere più efficiente dei tuoi loop costanti di Reference.isEnqueued() checks.

La scelta su quale tipo di riferimento usare è più complicata e dipende da quando si desidera essere avvisati e dal tipo di informazioni sull'oggetto che è necessario rendere disponibile. In particolare, guarderei anche PhantomReference come alternativa a WeakReference.

È un po 'rotonda, ma aggiungi elementi a ReferenceQueue passando la coda nel loro costruttore, per esempio:

Foo targetFoo; /* stuff */
ReferenceQueue<Object> refq = new ReferenceQueue<Object>();
WeakReference<Foo> pr = new WeakReference(targetFoo, refq);

In un thread separato, puoi eseguire il loop e attendere quando si verificano cambiamenti:

Reference<Object> ref = fooQueue.remove(); // Blocks, poll() is also possible

In questo modo, puoi avere un codice che monitora quando determinati oggetti non sono più strongmente raggiungibili.

PS: Dal momento che il% originale di co_de potrebbe essere effettivamente eliminato, un modo per mantenere le informazioni su di esso è creare la sottoclasse di Foo , una che memorizza le informazioni su Reference in modo che tu possa accedervi in seguito.

Foo targetFoo; /* stuff */
ReferenceQueue<Object> refq = new ReferenceQueue<Object>();
// Use custom subclass of WeakReference
MyReference<Foo> ref = new MyReference(targetFoo, refq);
ref.setStuff("hello");

// Later, in another thread, etc.

MyReference<Object> ref = (MyReference<Object>) fooQueue.remove();
String msg = ref.getStuff();
    
risposta data 12.05.2014 - 20:27
fonte

Leggi altre domande sui tag