Domanda

È necessario impostare tutti gli oggetti di null (Nothing in VB.NET) una volta che hai finito con loro?

Capisco che in .NET è essenziale disporre di uno qualsiasi di istanze di oggetti che implementano l' IDisposable interfaccia per liberare alcune risorse, anche se l'oggetto può essere ancora qualcosa dopo che è disposto (e quindi la isDisposed la struttura in moduli), quindi immagino che si può ancora risiedono in memoria, o almeno in parte?

So anche che quando un oggetto esce dall'ambito essa è segnalata per la raccolta pronto per il passo successivo del garbage collector (anche se questo può richiedere del tempo).

Quindi, con questo in mente, l'impostazione di null velocizzare il sistema per rilasciare la memoria, in quanto non dispone di un lavoro che non è più nel campo di applicazione e sono eventuali effetti collaterali male?

Articoli di MSDN non farlo mai in esempi e attualmente faccio questo, come io non vedere il male.Tuttavia mi sono imbattuto in una miscela di opinioni commenti sono utili.

È stato utile?

Soluzione

Karl è assolutamente corretto, non c'è bisogno di impostare gli oggetti null dopo l'uso.Se un oggetto implementa IDisposable, solo assicuratevi di chiamare IDisposable.Dispose() quando hai finito con quello oggetto avvolto in un try..finally, o, un using() blocco).Ma anche se non si ricorda di chiamare Dispose(), il finaliser metodo sull'oggetto dovrebbe essere chiamata Dispose() per voi.

Ho pensato che questo era un buon trattamento:

Scavando nel IDisposable

e questo

Comprensione IDisposable

Non c'è nessun punto nel tentativo di indovinare la GC e le sue strategie di gestione, perché si tratta di auto tuning e opaco.C'è stata una buona discussione circa il funzionamento interno con Jeffrey Richter su Dot Net Rocce qui: Jeffrey Richter sul Modello di Memoria di Windows e Richters libro CLR via C# capitolo 20 è un ottimo trattamento:

Altri suggerimenti

Un altro motivo per evitare l'impostazione di oggetti a null quando si è fatto con loro è che si può effettivamente mantenere in vita più a lungo.

ad es.

void foo()
{
    var someType = new SomeType();
    someType.DoSomething();
    // someType is now eligible for garbage collection         

    // ... rest of method not using 'someType' ...
}

permetterà l'oggetto di cui da someType da GC piacerebbe dopo la chiamata a "DoSomething" ma

void foo()
{
    var someType = new SomeType();
    someType.DoSomething();
    // someType is NOT eligible for garbage collection yet
    // because that variable is used at the end of the method         

    // ... rest of method not using 'someType' ...
    someType = null;
}

a volte può mantenere l'oggetto in vita fino alla fine del metodo.Il JIT di solito ottimizzato di distanza l'assegnazione di null, in modo che entrambi i bit di codice finiscono con l'essere stesso.

No non null oggetti.È possibile controllare http://codebetter.com/blogs/karlseguin/archive/2008/04/27/foundations-of-programming-pt-7-back-to-basics-memory.aspx per ulteriori informazioni, ma di impostare le cose a null non fare nulla, tranne che sporca il codice.

Inoltre:

using(SomeObject object = new SomeObject()) 
{
  // do stuff with the object
}
// the object will be disposed of

In generale, non c'è bisogno di null oggetti dopo l'uso, ma in alcuni casi credo sia una buona pratica.

Se un oggetto implementa IDisposable e memorizzato in un campo, penso che è bene null, proprio per evitare di usare il disposto dell'oggetto.I bug di questo tipo può essere doloroso:

this.myField.Dispose();
// ... at some later time
this.myField.DoSomething();

Buono a null il campo dopo lo smaltimento, e ottenere un NullPtrEx destra della riga in cui il campo viene utilizzato di nuovo.In caso contrario, si potrebbe incorrere in alcuni criptici bug lungo la linea (a seconda esattamente ciò che DoSomething fa).

Le probabilità sono che il codice non è strutturato abbastanza saldamente, se si sente il bisogno di null le variabili.

Ci sono un certo numero di modi per limitare l'ambito di applicazione di una variabile:

Come detto da Steve Tranby

using(SomeObject object = new SomeObject()) 
{
  // do stuff with the object
}
// the object will be disposed of

Allo stesso modo, si può semplicemente utilizzare le parentesi graffe:

{
    // Declare the variable and use it
    SomeObject object = new SomeObject()
}
// The variable is no longer available

Trovo che l'utilizzo di parentesi graffe senza alcun "titolo" per pulire il codice e renderlo più comprensibile.

L'unica volta che si dovrebbe impostare una variabile null è quando la variabile non va al di fuori del campo di applicazione e non è più necessario, i dati ad esso associati.Altrimenti non c'è bisogno.

In generale non c'è bisogno di impostare a null.Ma si supponga di avere una funzionalità di ripristino in classe.

Allora si potrebbe fare, perché non si desidera chiamare dispose due volte, dal momento che alcuni Smaltire non può essere attuato correttamente e gettare Sistema.ObjectDisposed eccezione.

private void Reset()
{
    if(_dataset != null)
    {
       _dataset.Dispose();
       _dataset = null;
    }
    //..More such member variables like oracle connection etc. _oraConnection
 }

questo tipo di "non c'è bisogno di impostare gli oggetti null dopo l'uso" non è del tutto esatto.Ci sono volte in cui è necessario NULL la variabile prima di gettarlo.

Sì, si dovrebbe SEMPRE chiamare .Dispose() o .Close() su tutto ciò che è quando si è fatto.Sia handle di file, connessioni di database o di oggetti monouso.

Separata da che è molto pratico, il modello di LazyLoad.

Dire di avere e creare un'istanza ObjA di class A. Class A ha una proprietà pubblica chiamata PropB di class B.

Internamente, PropB utilizza la variabile privata di _B di default è null.Quando PropB.Get() è utilizzato, controlla per vedere se _PropB è null e se lo è, apre le risorse necessarie per creare un'istanza di un B in _PropB.Si ritorna quindi _PropB.

Per la mia esperienza, questo è davvero un trucco molto utile.

Dove il bisogno di null viene è se si reimpostare o modificare in qualche modo che il contenuto di _PropB sono il figlio del precedente, i valori di A, sarà necessario Smaltire E null fuori _PropB così LazyLoad può reset per recuperare il giusto valore, SE il codice lo richiede.

Se fate solo _PropB.Dispose() e, dopo poco tempo si aspettano il controllo di null per LazyLoad per avere successo, non sarà nullo, e sarete guardando i dati non aggiornati.In effetti, si deve null, dopo Dispose() solo per essere sicuri.

Vorrei fosse il contrario, ma ho ottenuto il codice di diritto ora presente questo comportamento dopo un Dispose() su un _PropB e al di fuori della funzione chiamante che ha fatto il Dispose (e quindi quasi al di fuori dell'ambito), il privato prop ancora non è nullo, e i dati non aggiornati, è ancora lì.

Infine, il disposto proprietà null, ma che non deterministico dal mio punto di vista.

Il motivo, come dbkk allude è che il contenitore principale (ObjA con PropB) è mantenere l'istanza di _PropB nell'ambito, nonostante la Dispose().

Ci sono alcuni casi in cui ha senso un riferimento null.Per esempio, quando si sta scrivendo una raccolta--come una coda a priorità--e dal contratto, che non dovrebbe essere la conservazione di tali oggetti vivi per il cliente dopo che il client ha rimosso dalla coda.

Ma questo genere di cose solo questioni di lunga durata, collezioni.Se la coda non sta andando a sopravvivere alla fine della funzione in cui è stata creata, quindi conta molto meno.

Su tutto, davvero non dovrebbe preoccuparsi.Lasciate che il compilatore e GC fare il loro lavoro in modo che si può fare il vostro.

Date un'occhiata a questo articolo così: http://www.codeproject.com/KB/cs/idisposable.aspx

Per la maggior parte, l'impostazione di un oggetto null non ha alcun effetto.L'unica volta che si dovrebbe essere sicuri di farlo è se si lavora con un "oggetto di grandi dimensioni", che è maggiore di quanto 84K dimensioni (come bitmap).

Stefano Cleary spiega molto bene in questo post: Devo Impostare le Variabili nulla per Aiutare il Garbage Collection?

Dice:

La Risposta Breve, per gli Impazienti Sì, se la variabile è un campo statico, o se si sta scrivendo un enumerabile metodo (utilizzando resa return) o un metodo asincrono (utilizzando async e await).In caso contrario, no.

Questo significa che, in normali metodi (non enumerabile e non asincrona), non si imposta le variabili locali, i parametri del metodo di istanza o campi a null.

(Anche se sei di attuazione IDisposable.Smaltire, è comunque consigliabile non impostare le variabili a null).

La cosa importante che si dovrebbe prendere in considerazione è Campi Statici.

Campi statici sono sempre root oggetti, e , quindi, sono sempre considerato “vivo” dal garbage collector.Se un campo statico che fa riferimento a un oggetto che non è più necessario, esso può essere impostato a null in modo che il garbage collector trattare come idonei per la raccolta.

Impostazione statica campi a null è privo di significato se l'intero processo di arresto.L'intero heap è circa la procedura di garbage collection, a quel punto, tra tutti gli oggetti della directory principale.

Conclusione:

Campi statici;che su di esso.Tutto il resto è un spreco di tempo.

Credo che alla progettazione del GC le parti, non è possibile velocità GC con l'annullamento.Sono sicuro che si preferisce non preoccuparsi se stessi con come e quando e GC corre -- trattare come questo onnipresente Essere proteggere e vegliare e per voi...(archi a testa in giù, alza il pugno al cielo)...

Personalmente, mi capita spesso di impostare in modo esplicito variabili a null quando mi sono fatto con loro come una forma di documentazione.Io non dichiarare, uso, quindi impostare a null più tardi-mi null subito dopo non sono più necessari.Sto dicendo, in modo esplicito, "io sono ufficialmente a che fare con te...essere andato..."

È necessario distruggere in un GC piacerebbe lingua?No.È utile per il GC?Forse sì, forse no, non si sa per certo, dal design davvero non riesco a controllarlo, e nonostante oggi la risposta con questa versione o che, in futuro GC implementazioni potrebbe cambiare la risposta di là del mio controllo.Inoltre, se/quando l'annullamento è ottimizzato è poco più di una fantasia commento se si vuole.

Io penso che se si rende più chiaro il mio intento per il prossimo povero sciocco che segue le mie orme, e se "potrebbe" potenzialmente aiutare GC a volte, quindi ne vale la pena per me.Soprattutto mi fa sentire in ordine e chiaro, e Mongo piace sentirsi ordinato e chiaro.:)

Io la guardo come questo:Linguaggi di programmazione esistono per permettere alle persone di dare loro un'idea di intenti e di un compilatore di un processo di richiesta di cosa fare, il compilatore converte tale richiesta in una lingua diversa (a volte più di uno) per una CPU -- la CPU(s), potrebbe dare un grido che cosa la lingua utilizzata, la tua scheda impostazioni, commenti, stilistica accenti, i nomi delle variabili, etc.-- una CPU di tutto il flusso di bit che indica quali registri e codici operativi e posizioni di memoria a girarsi.Molte cose scritte nel codice non convertire in quello che ha consumato dalla CPU in sequenza che abbiamo specificato.Il nostro C, C++, C#, Lisp, Babel, assembler o qualsiasi altra cosa è la teoria, piuttosto che la realtà, scritto come una dichiarazione di lavoro.Quello che vedi non è quello che si ottiene, sì, anche in linguaggio assembler.

Capisco la mentalità di "cose inutili" (come le righe vuote) "non sono niente, ma il rumore e il disordine del codice." Che mi è stato in precedenza nella mia carriera;Sono assolutamente ottenere che.In questo frangente mi chino verso di ciò che rende il codice più chiaro.Non è che io sono l'aggiunta di 50 linee di "rumore" per i miei programmi -- si tratta di un paio di linee di qua o di là.

Ci sono eccezioni ad ogni regola.In scenari In cui volatile memoria, la memoria statica, condizioni di gara, singleton, l'utilizzo di dati "obsoleti" e quel tipo di marciume, che è diverso:è NECESSARIO gestire la vostra memoria, bloccare e disarmare, come a proposito, perché la memoria non è parte del GC piacerebbe Universo -- speriamo che tutti capiscano che.Il resto del tempo con GC piacerebbe lingue è una questione di stile piuttosto che per necessità o la garanzia di un incremento delle prestazioni.

Alla fine della giornata, assicurarsi di aver compreso ciò che è idoneo per GC e cosa non lo è;blocco, smaltire, e di annullare in modo appropriato;la cera, la cera;breathe in, breathe out;e per tutto il resto dico:Se ci si sente bene, farlo.Il vostro chilometraggio può variare...come si deve...

Alcuni oggetti si supponga che il .dispose() metodo che impone la risorsa che deve essere rimosso dalla memoria.

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