2013-04-16 12 views
5

Mi chiedo se si ritenga una buona pratica rimuovere i riferimenti (impostandoli su null) su oggetti per aiutare il Java Garbage Collector.È buona norma rimuovere i riferimenti per aiutare il GC?

Ad esempio, supponiamo di avere una classe con due campi, uno dei quali richiede molta memoria. Se sai che ne hai solo bisogno per una particolare elaborazione, puoi annullarla subito dopo per aiutare il GC.

Supponiamo che io abbia davvero bisogno che quei due siano campi, e non solo variabili interne, quindi heavyObject1 non può essere fuori portata alla fine del metodo.

Faresti questo come pratica generale?

public class TestClass { 

    public static Object heavyObject1; 
    public static Object object2; 

    private static void action() { 
    object2 = doSomething(heavyObject1); 

    heavyObject1 = null; //is this good? 
    } 
} 
+0

Il problema con questo comportamento è che è incompatibile con i campi finali e pertanto rende il codice più difficile da thread sicuro. – SpaceTrucker

+0

"Dereferimento" indica il recupero della cosa a cui si fa riferimento. L'ho modificato e cambiato. – delnan

risposta

8

Di solito non è necessario.

E 'una buona idea nel seguente circostanza specifica:

  • L'oggetto è di grandi dimensioni (cioè grande abbastanza per voi a cura)
  • sei sicuro che l'oggetto non sarà necessario ancora una volta
  • l'oggetto non uscirà di portata altrimenti (ad esempio, è conoscere l'oggetto circostante non sarà essere garbage collection)

Tuttavia, se ti trovi in ​​questa situazione, sospetto comunque che tu abbia un odore di progettazione: perché l'oggetto interno ha una portata/durata così diversa dall'oggetto che lo racchiude? Questo mi rende sospettoso, perché di solito quando costruisci un grafico oggetto con composizione ti aspetti che gli oggetti composti abbiano vite simili.

0

E 'certamente non cattiva pratica di assegnare null ai riferimenti se non si desidera più utilizzare tale oggetto. Tuttavia, è è cattive abitudini di contare sul GC per raccoglierli in qualsiasi momento presto o per tutto durante l'esecuzione del programma.

0

No, non è necessario. Appena heavyObject1 non è compreso, verrà comunque contrassegnato per GC.

+2

Se si tratta di un campo, non andrà fuori dal campo di applicazione fino a quando l'oggetto in cui si trova non sarà più disponibile. –

2

Nella maggior parte dei casi, non è necessario impostare l'oggetto su null come garbage collection. Se si decalre l'oggetto in ambito appropriato (livello metodo, livello di istanza o livello classe), l'oggetto sarà irraggiungibile immediatamente dopo il suo utilizzo e sarà idoneo per la garbage collection.

+0

'heavyObject1' non può uscire dall'ambito finché' TestClass' non viene spostato, poiché si tratta di un campo. – Alphaaa

+1

Correggere ... Ma se si sente la necessità di renderlo null, significa che l'ambito di heavyObject1 non è stato definito correttamente. Dovrebbe essere a livello di istanza o di metodo. – JRR

0

Come generale pratica , no, perché non è necessario.

Ci sono casi speciali - Posso immaginare una classe di lunga durata, ad esempio, che ha una lunga lista di oggetti che consumano memoria con cui fa qualcosa una volta e poi aspetta un periodo prima di sostituire quella lista con un'altra elenco. Potrebbe anche annullare l'elenco mentre stai aspettando, non danneggerà nulla e potrebbe impedire al programma di finire con entrambe le liste contemporaneamente.

Ma qui sta di nuovo il principio "non necessario".Non puoi contare sul GC da eseguire durante un determinato periodo, quindi il programma deve supportare entrambi questi elenchi nello stesso momento, quindi non rende il tuo programma praticabile se non lo era prima.

E PER FAVORE, non incoraggiare le persone a fare una "regola" a riguardo. Quando penso a tutto il codice ho letto dove qualcuno mette "finale" di fronte a (quasi) tutte le variabili che (pensano) non cambieranno dopo l'inizializzazione, rendendo il codice meno leggibile e convincendomi che il programmatore aveva nessuna comprensione del miglioramento della velocità che si supponeva stessero facendo ...

0

No. Non è generalmente una buona pratica per i campi o gli abitanti del posto null.

Nella maggior parte dei casi l'oggetto il cui campo si sta annullando diventerà irraggiungibile prima dell'esecuzione del GC. Se ciò accade, i cicli della CPU che hai speso per azzerare il campo dell'oggetto andranno sprecati.

Le uniche situazioni in cui è necessario,/buone da null campi/i locali sono dove:

  1. è probabile che l'oggetto padre sarà ancora raggiungibile quando le piste GC, ED
  2. la l'oggetto figlio (grafico) è abbastanza grande per la quantità di memoria conservata significativa ... rispetto alla dimensione totale dell'heap.

Si potrebbe anche farlo, se si implementa una classe che è destinato per essere utilizzato in una vasta gamma di situazioni ... e alcune di queste situazioni potrebbero rientrare i criteri di cui sopra. (Ad esempio, un'implementazione della struttura dati in cui le istanze potrebbero aumentare.)

0

Gli oggetti di dereferenziazione non sono necessari a meno che la classe non stia gestendo la propria memoria o la classe stia memorizzando nella cache le risorse, quindi i riferimenti obsoleti dovrebbero essere eliminati.

Problemi correlati