Nastavení objektů null / Nothing po použití v .NET

hlasů
173

Byste měli nastavit všechny objekty na null( Nothingv VB.NET), jakmile jste ukončili s nimi?

Chápu, že v .NET je nezbytné, aby zlikvidovali jakékoliv instance objektů, které implementují IDisposablerozhraní k uvolnění některé zdroje, i když objekt může být ještě něco poté, co je umístěna (tedy i isDisposedmajetek ve formulářích), takže předpokládám, že to může být stále uložena v paměti, nebo alespoň částečně?

Také vím, že když objekt dostane mimo rozsah je pak označen k vyzvednutí připraven k dalšímu průchodu garbage collector (i když to může trvat déle).

Takže s tím na mysli to bude nastavení pro nullurychlení systému uvolňuje paměť, neboť nemusí fungovat na to, že již není co do rozsahu a jsou tyto případné negativní vedlejší účinky?

články MSDN nikdy to v příkladech a v současné době jsem to dělat, co nevidím škod. Nicméně jsem narazil směsi stanovisek, takže případné připomínky jsou užitečné.

Položena 05/08/2008 v 21:14
zdroj uživatelem
V jiných jazycích...                            


13 odpovědí

hlasů
66

Karl je naprosto správné, není třeba nastavovat objekty na null po použití. Pokud objekt implementuje IDisposable, jen se ujistěte, volat IDisposable.Dispose(), když budete hotovi s tímto objektem (zabalené v try.. finally, nebo, což je using()blok). Ale i když si nepamatujete volat Dispose()metoda finaliser na předmětu je třeba volat Dispose()pro vás.

Myslel jsem, že to byl dobrý léčba:

Kopání do IDisposable

a tohle

pochopení IDisposable

Neexistuje žádný bod, ve snaze druhý odhadnout GC a jeho strategie řízení, protože je to automatického vyladění a neprůhledný. Tam byla dobrá diskuse o vnitřní činnost s Jeffrey Richtera na Dot Net skály zde: Jeffrey Richter na Windows Memory modelu a Richters knižní CLR pomocí C # kapitole 20 má velkou ošetření:

Odpovězeno 05/08/2008 v 21:56
zdroj uživatelem

hlasů
33

Dalším důvodem, aby se zabránilo nastavení objekty null, když jste udělal s nimi je, že může skutečně udržet naživu déle.

např

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

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

Umožní objekt položenou someType být GC'd po volání „DoSomething“, ale

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;
}

Někdy může udržet objekt naživu až do konce metody. JIT se obvykle optimalizované pryč přiřazení null , takže oba bity kódu skončit stejně.

Odpovězeno 15/08/2008 v 15:43
zdroj uživatelem

hlasů
15

No ne objekty null. Můžete se podívat na http://codebetter.com/blogs/karlseguin/archive/2008/04/27/foundations-of-programming-pt-7-back-to-basics-memory.aspx pro více informací, ale nastavení věci null nebude dělat nic, kromě špinavého kódu.

Odpovězeno 05/08/2008 v 21:23
zdroj uživatelem

hlasů
7

Obecně platí, že není nutné, aby objekty null po použití, ale v některých případech jsem si, že je to dobré praxe.

Pokud objekt implementuje IDisposable a je uložen v poli, myslím, že je dobré, aby to null, jen proto, aby se zabránilo používání likvidovaného objektu. Chyby z následujícího druhu mohou být bolestivé:

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

Je dobré null pole po likvidaci to, a získat NullPtrEx přímo na trati, kde se pole opět použit. V opačném případě můžete narazit na nějaké záhadné chyby v řadě (v závislosti na přesně to, co dělá DoSomething).

Odpovězeno 09/08/2008 v 12:16
zdroj uživatelem

hlasů
7

Taky:

using(SomeObject object = new SomeObject()) 
{
  // do stuff with the object
}
// the object will be disposed of
Odpovězeno 05/08/2008 v 21:37
zdroj uživatelem

hlasů
6

Je pravděpodobné, že váš kód není strukturován dost pevně, pokud máte pocit, že je třeba do nullproměnné.

Existuje celá řada způsobů, jak omezit rozsah proměnné:

Jak uvádí Steve Tranby

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

Stejně tak můžete jednoduše použít složené závorky:

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

Zjistil jsem, že použití složené závorky bez jakýchkoli „okruh“, aby skutečně vyčistit kód a pomoci, aby bylo srozumitelnější.

Odpovězeno 09/08/2008 v 13:13
zdroj uživatelem

hlasů
5

Obecně není třeba nastavit na hodnotu null. Ale předpokládejme, že máte reset funkce ve vaší třídě.

Pak byste měli udělat, protože nechcete volat disponovat dvakrát, protože některé z odložte nemusí být správně prováděny a hodit System.ObjectDisposed výjimku.

private void Reset()
{
    if(_dataset != null)
    {
       _dataset.Dispose();
       _dataset = null;
    }
    //..More such member variables like oracle connection etc. _oraConnection
 }
Odpovězeno 17/04/2012 v 09:55
zdroj uživatelem

hlasů
4

Jediný okamžik, kdy byste měli nastavit proměnnou na hodnotu null, je-li proměnná nepřejde mimo rozsah a již nebudete potřebovat data s ním spojené. V opačném případě není nutné.

Odpovězeno 05/08/2008 v 21:32
zdroj uživatelem

hlasů
3

Tento druh „není nutné nastavovat objekty null po použití“ není úplně přesné. Tam jsou časy, které potřebujete, aby NULL proměnnou po likvidaci ji.

Ano, měli byste vždy zavolat .Dispose()nebo .Close()na cokoli, co má, když jste hotovi. Ať už je to soubor úchyty, databázové připojení nebo jednorázové předměty.

Oddělený od toho je velmi praktický vzor LazyLoad.

Řekněme, že mám i instance ObjAof class A. Class AMá veřejný majetek s názvem PropBof class B.

Interně, PropBpoužívá vlastní proměnnou _Ba výchozí NULL. Když PropB.Get()je použit, to zkontroluje, zda _PropBje null, a pokud ano, otevírá prostředky potřebné k vytvoření instance BINTO _PropB. Poté se vrátí zpět _PropB.

Mých zkušeností je to opravdu užitečný trik.

V případě, že je třeba, aby null přichází v je, pokud si obnovit nebo změnit nějakým způsobem, že obsah _PropBbyl dítě z předchozích hodnot A, budete muset zlikvidovat a nula se _PropBtak LazyLoad můžete obnovit, aby přinesla tu správnou hodnotu, pokud kód to vyžaduje.

Máte-li dělat jen _PropB.Dispose()a krátce poté, co očekávají, že kontrola null pro LazyLoad uspět, nebude to null, a budete se dívat na zastaralých údajů. Ve skutečnosti, je třeba jej null po Dispose()jen pro jistotu.

Určitě přál, aby to bylo jinak, ale mám kód právě teď vykazuje toto chování Po Dispose()Na ploše _PropBi vně volání funkce, které dělal na správné likvidaci (a tedy téměř mimo rozsah), soukromý prop stále není null, a stale dat je tam pořád.

Nakonec se převedl majetek bude null ven, ale že to bylo non-deterministický z mého pohledu.

Jádro z důvodů, jak dbkk odkazovalo je, že mateřská nádoba ( ObjAs PropB), se udržuje instance _PropBv rozsahu, navzdory Dispose().

Odpovězeno 11/04/2012 v 02:12
zdroj uživatelem

hlasů
1

Podívejte se na tento článek, stejně: http://www.codeproject.com/KB/cs/idisposable.aspx

Z větší části, nastavení objektu na null nemá žádný vliv. Jediný okamžik, kdy byste měli být jisti, že k tomu je, pokud pracujete s „velký objekt“, což je jedna větší než 84k ve velikosti (jako bitmapy).

Odpovězeno 17/08/2008 v 05:46
zdroj uživatelem

hlasů
1

Tam jsou některé případy, kdy to má smysl, aby null reference. Například, když píšete kolekce - jako prioritní fronty - a vaši smlouvu, neměli byste se držet tyto objekty naživu klienta poté, co klient je odstranil z fronty.

Ale tyhle věci záleží pouze na dlouho žil sbírky. Pokud fronta nebude to přežít konec funkce byla vytvořena v, pak je to důležité spoustu méně.

Na celek, opravdu neměli obtěžovat. Nechť kompilátor a GC dělat svou práci, takže si můžete udělat vy.

Odpovězeno 05/08/2008 v 21:46
zdroj uživatelem

hlasů
0

Věřím, že záměrné GC implementors nelze urychlit GC s nullification. Jsem si jistý, že by tě raději si starosti s tím, jak / kdy GC běží - zacházet s ní takhle všudypřítomná bytost chránit a hlídat i pro vás ... (luky hlavou dolů, vyvolává pěstí k nebi) .. ,

Osobně jsem často explicitně nastavit proměnné na hodnotu null, když jsem udělal s nimi jako formu vlastní dokumentace. Nechci deklarovat, použijte pak nastavena na hodnotu null později - Okamžitě jsem null po oni jsou již není potřeba. Říkám výslovně „Jsem oficiálně udělal s tebou ... pryč ...“

Je nutné rušit v jazyce GC'd? Ne. Je to užitečné pro GC? Možná ano, možná ne, nevím jistě, záměrné jsem opravdu nemůže ovládat, a to bez ohledu na dnešní odpovědi s touto verzí, nebo to, že budoucí implementace GC může změnit odpověď mimo mou kontrolu. Navíc v případě, / když nulling je optimalizována se, že to je málo více než vymyšleného komentáři chcete-li.

I zjistit, jestli to dělá můj záměr jasnější k dalšímu špatnému blázna, který následuje v mých stopách, a je-li to „mohl“ potenciálně pomoci GC někdy, pak to stojí za to na mě. Většinou to cítím čistý a jasný, a Mongo rád cítit čistý a jasný. :)

Dívám se na to takhle: Programovací jazyky existují, aby lidé dát dalším lidem představu o záměru a kompilátor žádost o zaměstnání o tom, co dělat - překladač převádí tuto žádost do jiného jazyka (někdy více) pro CPU - CPU (s) by mohl dát sranda, co jazyk, který jste použili, nastavení karet, komentáře, stylistické důrazy, názvy proměnných, atd - CPU to všechno o bitového toku, který říká, co registruje a operační kódy a paměťových míst se kroutit. Mnoho věcí napsaných v kódu nemají převedla co se spotřebuje CPU v pořadí máme specifikované. Naše C, C ++, C #, Lisp, Babel, assembler, nebo to, co je teorie, spíše než skutečnost, psaný jako prohlášení o pracovní činnosti. To, co vidíte, není to, co dostanete, ano, dokonce v assembleru.

Já pochopit myšlení „nepotřebných věcí“ (jako jsou prázdné řádky) „nejsou nic jiného než hluk a nepořádek nahoru kódu.“ To jsem byl já dříve v mé kariéře; Naprosto chápu. V tomto okamžiku se přikláním k toho, co dělá kód jasnější. Není to jako bych přidat i 50 řádků „šumu“ do svých programů - to je několik řádků tam či onam.

Tam jsou výjimky z žádného pravidla. Ve scénářích s energeticky nezávislé paměti, statické paměti, podmínky závodu, singletons, použití „zastaralých“ údajům a všechny takové hniloby, to je něco jiného: Musíte spravovat své vlastní paměť, zamykání a rušit jako na zavolanou, protože paměť není součástí GC'd Universe - doufejme, že každý chápe, že. Zbytek času s GC'd jazyků je to otázka stylu, nikoli nezbytnosti nebo zaručené zvýšení výkonu.

Na konci dne, ujistěte se, že jste pochopili, co je způsobilý pro GC a co ne; uzamknout, nakládat a anulovat vhodně; vosk na, vosk pryč; nádech výdech; a všechno ostatní říkám: Pokud se cítí dobře, udělej to. Váš se může lišit ... jak by měl ...

Odpovězeno 10/05/2016 v 13:07
zdroj uživatelem

hlasů
-1

Někteří namítají, Předpokládám, že .dispose()způsob, který nutí zdroje, které mají být odstraněny z paměti.

Odpovězeno 05/08/2008 v 21:21
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more