kzen.dev
  • Întrebări
  • Tag-uri
  • Utilizatori
Notificări
Recompense
Înregistrare
După înregistrare, veți primi notificări despre răspunsurile și comentariile la întrebările DVS.
Logare
Dacă aveţi deja un cont, autentificaţi-vă pentru a verifica notificările noi.
Aici vor fi recompensele pentru întrebările, răspunsurile și comentariile adăugate sau modificate.
Mai mult
Sursă
Editează
 John
John
Question

Setarea Obiecte pentru a Nul/Nimic după utilizare în .NET

Ar trebui să vă setați toate obiectele pentru a null ("Nimic" în VB.NET) după ce ați terminat cu ei?

Am înțeles că în .NET este esențial de a dispune de orice instanțe de obiecte care pune în aplicare IDisposable de interfață pentru a elibera unele resurse deși obiectul poate fi încă ceva după ce este eliminat (prin urmare `isDisposed de proprietate în forme), deci presupun că încă mai pot locui în memorie sau cel puțin în parte?

De asemenea, știu că atunci când un obiect iese din domeniul de aplicare este apoi marcat de colectare gata pentru următoarea trecere de colectorul de gunoi (deși acest lucru poate dura un timp).

Deci, cu asta în minte va setare a null accelera sistemul eliberarea de memorie, deoarece nu trebuie să afle că nu mai este în domeniul de aplicare și sunt efecte secundare rău?

MSDN articole nu face acest lucru în exemple și în prezent fac asta ca eu nu pot văd ce-i rău. Cu toate acestea am venit peste un amestec de opinii, astfel încât orice comentarii sunt utile.

182 2008-08-05T20:14:10+00:00 15
Chris Catignani
Chris Catignani
Întrebarea editată 5 mai 2019 в 4:53
Programare
null
vb.net
memory-management
.net
c#
Solution / Answer
 Kev
Kev
5 august 2008 в 8:56
2008-08-05T20:56:28+00:00
Mai mult
Sursă
Editează
#8412917

Karl este absolut corect, nu este nevoie pentru a seta obiecte pentru a nul după utilizare. Dacă un obiect implementează IDisposable, doar asigurați-vă că sunațiIDisposable.Dispose()când're face cu acel obiect (înfășurat într-o "încerca" .. "în sfârșit", sau, ocu()bloc). Dar, chiar dacă tu nu't uitați să sunațiDispose(), la finaliser metoda pe obiect ar trebui să fie de asteptareDispose () pentru tine.

Am crezut că acest lucru a fost un bun tratament:

Săpat în IDisposable

și asta

Înțelegerea IDisposable

Nu e't orice punct în încercarea de a doua ghici GC și strategii de management, deoarece's tuning auto și opac. Acolo a fost o discuție bună despre mecanismele interioare cu Jeffrey Richter pe Dot Net Rocks aici: Jeffrey Richter pe Windows Model de Memorie și Richters carte CLR prin intermediul C# capitolul 20 are o mare tratament:

 Kev
Kev
Răspuns editat 28 noiembrie 2018 в 12:51
69
0
 Wilka
Wilka
15 august 2008 в 2:43
2008-08-15T14:43:34+00:00
Mai mult
Sursă
Editează
#8413016

Un alt motiv pentru a evita crearea de obiecte pentru a nul atunci când ați terminat cu ele este că poate de fapt să-i țină în viață pentru mai mult timp.

de exemplu

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

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

va permite obiectului denumit de someType să fie GC'd după apelul la "DoSomething" dar

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

uneori poate menține obiectul în viață până la sfârșitul metoda. De JIT, de obicei, va optimizat departe misiunea să null, astfel încât ambele bucăți de cod, sfârșesc prin a fi la fel.

36
0
Karl Seguin
Karl Seguin
5 august 2008 в 8:23
2008-08-05T20:23:33+00:00
Mai mult
Sursă
Editează
#8412845

Nici nu't null obiecte. Puteți verifica afară http://codebetter.com/blogs/karlseguin/archive/2008/04/27/foundations-of-programming-pt-7-back-to-basics-memory.aspx pentru mai multe informații, dar pentru a pune lucrurile la nul a câștigat't face nimic, cu excepția murdar codul.

Karl Seguin
Karl Seguin
Răspuns editat 5 august 2008 в 8:28
14
0
 dbkk
dbkk
9 august 2008 в 11:16
2008-08-09T11:16:04+00:00
Mai mult
Sursă
Editează
#8412980

În general, nu's nu este nevoie să null obiecte după utilizare, dar, în unele cazuri, am găsit-o's o practică bună.

Dacă un obiect implementează IDisposable și este stocat într-un domeniu, cred că's bine să null, doar pentru a evita folosirea obiect eliminate. Bug-uri de următoarele fel pot fi dureroase:

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

L's bun la nul pe teren dupa eliminarea, și a obține o NullPtrEx chiar la linie în cazul în care câmpul este folosit din nou. În caz contrar, s-ar putea rula în unele criptic bug pe linie (în funcție de exact ceea ce DoSomething nu).

7
0
Steve Tranby
Steve Tranby
5 august 2008 в 8:37
2008-08-05T20:37:30+00:00
Mai mult
Sursă
Editează
#8412898

De asemenea:

using(SomeObject object = new SomeObject()) 
{
  // do stuff with the object
}
// the object will be disposed of
7
0
 mbillard
mbillard
9 august 2008 в 12:13
2008-08-09T12:13:12+00:00
Mai mult
Sursă
Editează
#8413000

Sunt șanse ca codul nu este structurate suficient de bine, dacă vă simțiți nevoia de a null variabile.

Există o serie de moduri de a limita domeniul de aplicare a unei variabile:

După cum sa menționat de către Steve Tranby

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

În mod similar, puteți folosi pur și simplu acolade:

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

Mi se pare că, folosind acolade, fără nici o "rubrica" să curățați cod și de a ajuta face mai ușor de înțeles.

7
0
 Bob
Bob
5 august 2008 в 8:32
2008-08-05T20:32:48+00:00
Mai mult
Sursă
Editează
#8412871

Singura dată când ar trebui să setați o variabilă de nul este atunci când variabila nu ies din domeniul de aplicare și nu mai aveți nevoie de datele asociate cu acesta. Altfel nu este nevoie.

5
0
Munish Goyal
Munish Goyal
17 aprilie 2012 в 8:55
2012-04-17T08:55:49+00:00
Mai mult
Sursă
Editează
#8413026

În general, nu este nevoie pentru a seta la zero. Dar să presupunem că aveți o Resetare funcționalitate în clasa ta.

Atunci s-ar putea face, pentru că nu vreau să sun dispune de două ori, deoarece unele dintre Dispune nu pot fi puse în aplicare în mod corect și arunca Sistem.ObjectDisposed excepție.

private void Reset()
{
    if(_dataset != null)
    {
       _dataset.Dispose();
       _dataset = null;
    }
    //..More such member variables like oracle connection etc. _oraConnection
 }
5
0
 KenF
KenF
11 aprilie 2012 в 1:12
2012-04-11T01:12:07+00:00
Mai mult
Sursă
Editează
#8413025

acest fel de "nu este nevoie să setați obiecte pentru a nul după utilizare" nu este în întregime corecte. Există momente în care trebuie să NULL variabila după care dispune acesta.

Da, ar trebui să te sun MEREU `.Dispose () "sau".Close () pe ceva care are o atunci când ați terminat. Fie fișierul mânere, conexiuni la baza de date sau obiecte de unică folosință.

Separat de asta este foarte practic model de LazyLoad.

Spune că am și instanțiată ObjA de "clasa a". "Clasa a" are o proprietate publică numit PropB din "clasa B".

Pe plan intern, PropB folosește privat variabilă de _Bși implicit la null. Când PropB.Obține() este folosit, se verifică pentru a vedea dacă _PropB este nul și dacă este, se deschide resursele necesare pentru a instantia un " B " in _PropB. Apoi se întoarce _PropB.

La experiența mea, acest lucru este un truc util.

În cazul în care necesitatea de a nul vine este dacă resetați sau schimba în vreun fel faptul că conținutul de _PropBau copilul de valorile anterioare ale "A", va trebui să Eliminați ȘI null_PropB așa LazyLoad poate reseta pentru a aduce dreptul de valoare în CAZUL în care codul necesită.

Dacă faci numai _PropB.Dispose() și la scurt timp după aștepta null pentru a verifica LazyLoad pentru a reuși, nu va't fi nulă, și te'll fi uitat la datele vechi. În efect, trebuie să null după Dispose() doar pentru a fi sigur.

Sigur că am vrea să fie altfel, dar eu'am primit codul, acum prezintă acest comportament după o `Dispose () "pe o" _PropB și în afară de funcția de asteptare care a făcut Dispune (și, astfel, aproape în afara domeniului de aplicare), private prop încă nu't nul, iar datele vechi este încă acolo.

În cele din urmă, eliminate de proprietate va null, dar care's a fost non-deterministe din punctul meu de vedere.

Motivul de bază, ca dbkk face aluzie este că containerul părinte (ObjA " cu " PropB) este păstrarea exemplu de _PropB în aplicare, în ciudaDispose()`.

Siddharth Rout
Siddharth Rout
Răspuns editat 9 iunie 2012 в 4:56
3
0
 Ebleme
Ebleme
27 martie 2019 в 12:50
2019-03-27T00:50:13+00:00
Mai mult
Sursă
Editează
#8413028

Stephen Cleary explică foarte bine în acest post: Trebuie sa setez Variabile de la zero pentru a Sprijini Colectarea Gunoiului?

Spune:

Pe Scurt, pentru cei Nerăbdători Da, dacă variabila este un câmp static, sau dacă sunteți scris un enumerable metoda (folosind retur randament) sau o metodă asincron (folosind asincron și așteaptă). În caz contrar, nu.

Acest lucru înseamnă că, în metodele obișnuite (non-enumerable și non-asincron), nu setați variabilele locale, parametrii metoda, sau de exemplu câmpuri la null.

(Chiar daca esti de punere în aplicare IDisposable.Dispune, încă nu ar trebui să setați variabilele de null).

Cel mai important lucru pe care ar trebui să ia în considerare este Câmpuri Statice.

câmpuri Statice sunt întotdeauna rădăcină de obiecte, astfel încât acestea sunt întotdeauna considerat "viu" de colectorul de gunoaie. Dacă un câmp static se referă la un obiect care nu mai este necesar, ar trebui să fie setat la nul, astfel încât colectorul de gunoi va trata ca eligibile pentru colectare.

Setare câmpuri statice la nul este lipsit de sens dacă întregul proces este de a închide. Întreaga heap este pe cale de a fi gunoi colectate de la acel moment, inclusiv toate root obiecte.

Concluzie:

câmpuri Statice; asta e despre asta. Orice altceva este o pierdere de timp**.

 Ebleme
Ebleme
Răspuns editat 23 aprilie 2019 в 9:43
1
0
Scott Dorman
Scott Dorman
17 august 2008 в 4:46
2008-08-17T04:46:54+00:00
Mai mult
Sursă
Editează
#8413024

Aruncati o privire la acest articol, precum și: http://www.codeproject.com/KB/cs/idisposable.aspx

Pentru cea mai mare parte, stabilind un obiect la nul nu are nici un efect. Singura dată când ar trebui să fie sigur de a face acest lucru este în cazul în care lucrați cu o "obiect mare", care este unul mai mare decât 84K în dimensiune (cum ar fi bitmap).

Scott Dorman
Scott Dorman
Răspuns editat 1 noiembrie 2008 в 3:47
1
0
 Patrick
Patrick
5 august 2008 в 8:46
2008-08-05T20:46:08+00:00
Mai mult
Sursă
Editează
#8412907

Există unele cazuri în care este logic să null referințe. De exemplu, atunci când te're scris o colecție--ca o coadă prioritate-și prin contract, nu ar trebui't fi păstrarea acestor obiecte în viață pentru client după client are le-a eliminat din coadă.

Dar acest fel de lucru contează doar în timp a trăit colecții. Dacă coada's nu va supraviețui la sfârșitul funcției acesta a fost creat în, apoi contează mult mai puțin.

Pe ansamblu, ar trebui't deranjez. Lasa compilatorul și GC face locurile lor de muncă, astfel încât să puteți face a ta.

1
0
Thulani Chivandikwa
Thulani Chivandikwa
13 septembrie 2019 в 9:52
2019-09-13T09:52:55+00:00
Mai mult
Sursă
Editează
#8413029

Cred setare ceva de la zero este murdar. Imaginați-vă un scenariu în cazul în care elementul fiind stabilit acum este expus prin intermediul proprietate. Acum este cumva o bucată de cod accidental folosește această proprietate după elementul este eliminat, veți obține o excepție de referință nulă care necesită o anchetă pentru a afla exact ce se întâmplă.

Cred cadru de unică folosință va permite arunca ObjectDisposedException care este mai semnificativ. Nu setarea înapoi la nul va fi mai bine atunci pentru care motiv.

0
0
 John
John
10 mai 2016 в 1:07
2016-05-10T13:07:53+00:00
Mai mult
Sursă
Editează
#8413027

Cred că de proiectare a GC implementatori, puteți't accelera GC cu anulare. Am', sunt'd prefera să nu-ți faci griji cu cât/când GC ruleaza-l trateze ca acest omniprezente Nu protejarea și vizionarea de peste si pentru tine...(arcuri capul în jos, ridică pumnul spre cer)...

Personal, am de multe ori în mod explicit set de variabile pentru a nul când m-am'm făcut cu ei ca o formă de auto-documentare. Eu nu't declara, utilizați, apoi setat la nul mai târziu-eu nul imediat după ce au're nu mai este necesar. Am'm a spune, în mod explicit, "I'm-a terminat oficial cu tine...fi plecat..."

Este anularea necesară într-o GC'd limba? Nr. Este util pentru GC? Poate da, poate nu, nu't știu sigur, de design nu pot't de control, și indiferent de azi's a răspunde cu versiunea asta sau asta, viitorul GC implementari ar putea modifica răspunsul dincolo de controlul meu. În Plus, dacă/atunci când nulling este optimizat afară it's ceva mai mult decât o fantezie comentariu dacă vrei.

M-am gândit dacă mi se face o intenție clară la următoarea prostul care urmează în urmele mele, și dacă "poate" ajuta potential GC uneori, atunci's valoare de ea pentru mine. Cea mai mare parte mă face să mă simt curat și clar, și Mongo îi place să se simtă curat și clar. :)

Mă uit la o astfel de prognoze: limbaje de Programare există pentru a lăsa oamenii să dau și altora o idee de intenție și un compilator un loc de muncă cererea ce să fac ... compilatorul transformă această cerere într-o altă limbă (uneori mai multe) pentru un CPU-CPU(s) ar putea da doi bani pe ce limba ai folosit, fila setări, comentarii, accente stilistice, nume de variabile, etc. ... un CPU's tot despre fluxul de biți care se spune ce registre și opcodes și locații de memorie pentru a învârti. Multe lucruri scrise in codul nu't converti în ceea ce's consumată de către CPU în secvența pe care am specificat-o. C, C++, C#, Lisp, Babel, assembler sau ce este teorie, mai degrabă decât de realitate, scris ca o declarație de muncă. Ceea ce vezi nu este ceea ce veți obține, da, chiar și în limbajul assembler.

Eu nu inteleg mentalitatea de "lucruri inutile" (cum ar fi linii goale) "nu sunt nimic altceva decât zgomot și dezordine cod." Asta mi-a fost mai devreme în cariera mea; am înțeles asta. În acest moment mă aplec spre ceea ce face codul mai clar. L'nu am'm adăugând chiar și 50 de linii de "zgomot" pentru programele mele-it's câteva rânduri aici sau acolo.

Există excepții de la orice regulă. În scenarii cu o memorie volatila, memorie statică, condiții de rasă, singletons, utilizarea "vechi" de date și tot felul de putregai, ca's diferite: aveți NEVOIE pentru a gestiona propria ta memorie, blocarea și anularea ca apropos, pentru că memoria nu este o parte din GC'd Universul ... să sperăm că toată lumea înțelege asta. Restul de timp cu GC'd limbi it's o chestiune de stil, mai degrabă decât o necesitate sau un garantat impuls de performanță.

La sfârșitul zilei, asigurați-vă că ați înțeles ce este eligibil pentru GC și ce's nu; blocare, dispune, de a-și anula în mod corespunzător; wax on, wax off; respira, respira afară; și pentru tot ceea ce am spus: Dacă te simți bine, fă-o. Kilometraj dvs. poate varia...cum ar trebui...

0
0
 GateKiller
GateKiller
5 august 2008 в 8:21
2008-08-05T20:21:17+00:00
Mai mult
Sursă
Editează
#8412818

Un obiect presupun .dispose() metoda pe care forțele de resurse pentru a fi eliminat din memorie.

 T.S.
T.S.
Răspuns editat 7 august 2017 в 8:52
-1
0
Adăugati o întrebare
Categorii
Toate
Tehnologii
Cultură
Viață / Artă
Stiință
Profesii
Afaceri
Utilizatori
Toate
Nou
Populare
1
工藤 芳則
Înregistrat 6 zile în urmă
2
Ирина Беляева
Înregistrat 1 săptămână în urmă
3
Darya Arsenyeva
Înregistrat 1 săptămână în urmă
4
anyta nuam-nuam (LapuSiK)
Înregistrat 1 săptămână în urmă
5
Shuhratjon Imomkulov
Înregistrat 1 săptămână în urmă
ID
JA
KO
RO
RU
© kzen.dev 2023
Sursă
stackoverflow.com
în cadrul licenței cc by-sa 3.0 cu atribuire