Voglio sapere risorse non gestite. Qualcuno può darmi un'idea di base?
Voglio sapere risorse non gestite. Qualcuno può darmi un'idea di base?
Risposte:
Le risorse gestite in pratica significano "memoria gestita" gestita dal Garbage Collector. Quando non hai più riferimenti a un oggetto gestito (che utilizza la memoria gestita), Garbage Collector rilascerà (eventualmente) quella memoria per te.
Le risorse non gestite sono quindi tutto ciò che il garbage collector non conosce. Per esempio:
Normalmente si desidera rilasciare quelle risorse non gestite prima di perdere tutti i riferimenti che si hanno all'oggetto che le gestisce. Puoi farlo chiamando Dispose
quell'oggetto o (in C #) usando l' using
istruzione che gestirà la chiamata Dispose
per te.
Se trascuri Dispose
correttamente le tue risorse non gestite, il Garbage Collector alla fine lo gestirà per te quando l'oggetto che contiene quella risorsa è garbage collection (questa è "finalizzazione"). Ma poiché il garbage collector non è a conoscenza delle risorse non gestite, non può dire quanto male debba liberarle, quindi è possibile che il tuo programma funzioni male o esaurisca completamente le risorse.
Se implementi tu stesso una classe che gestisce risorse non gestite, spetta a te implementare Dispose
e Finalize
correttamente.
Dispose
o usare using
.
IDisposable
. Se una classe non implementa IDisposable
, allora si dovrebbe disporre di istanze di quella classe con using
o Dispose()
quando si è fatto con loro. Sulla base di questo, il tuo contrario detiene: Se una classe implementa IDisposable
, probabilmente contiene risorse non gestite internamente.
Alcuni utenti classificano i file aperti, le connessioni db, la memoria allocata, le bitmap, i flussi di file ecc. Tra le risorse gestite, altri tra quelli non gestiti. Quindi sono gestiti o non gestiti?
La mia opinione è che la risposta sia più complessa: quando apri un file in .NET, probabilmente usi una classe .NET integrata System.IO.File, FileStream o qualcos'altro. Poiché è una normale classe .NET, è gestita. Ma è un wrapper, che al suo interno fa il "lavoro sporco" (comunica con il sistema operativo usando Win32 DLL, chiamando funzioni di basso livello o addirittura istruzioni assembler) che aprono davvero il file. E questo è ciò che .NET non sa, non gestito. Ma forse puoi aprire il file da solo usando le istruzioni assembler e bypassando le funzioni dei file .NET. Quindi l'handle e il file aperto sono risorse non gestite.
Lo stesso con il DB: se usi un assembly DB, hai classi come DbConnection ecc., Sono note a .NET e gestite. Ma avvolgono il "lavoro sporco", che non è gestito (allocare memoria sul server, stabilire una connessione con esso, ...). Se non usi questa classe wrapper e apri un socket di rete da solo e comunichi con il tuo strano database usando alcuni comandi, non è gestito.
Queste classi wrapper (File, DbConnection ecc.) Sono gestite, ma al loro interno usano risorse non gestite allo stesso modo di te, se non usi i wrapper e fai il "lavoro sporco" da solo. E quindi questi wrapper implementano i modelli Dispose / Finalize. È loro responsabilità consentire al programmatore di rilasciare risorse non gestite quando il wrapper non è più necessario e di rilasciarle quando il wrapper viene raccolto. Il wrapper verrà correttamente raccolto dall'immondizia dal Garbage Collector, ma le risorse non gestite all'interno verranno raccolte utilizzando il modello Dispose / Finalize.
Se non si utilizzano classi wrapper .NET o di terze parti integrate e file aperti da alcune istruzioni assembler, ecc. Nella propria classe, questi file aperti non sono gestiti e DEVE implementare il modello dispose / finalize. In caso contrario, si verificherà una perdita di memoria, una risorsa bloccata per sempre ecc. Anche quando non la si utilizza più (operazione di file completata) o anche dopo la chiusura dell'applicazione.
Ma la tua responsabilità è anche quando usi questi wrapper. Per coloro che implementano dispose / finalize (li riconosci, che implementano IDisposable), implementa anche il tuo pattern dispose / finalize e Dispose anche questi wrapper o dai loro il segnale per liberare le loro risorse non gestite. In caso contrario, le risorse saranno disponibili dopo un periodo di tempo indefinito, ma è opportuno rilasciarlo immediatamente (chiudere immediatamente il file e non lasciarlo aperto e bloccato per diversi minuti / ore a caso). Quindi nel metodo Dispose della tua classe chiami i metodi Dispose di tutti i wrapper usati.
unmanaged vs managed resources
Una "risorsa non gestita" non è una cosa, ma una responsabilità. Se un oggetto possiede una risorsa non gestita, ciò significa che (1) alcune entità al di fuori di esso sono state manipolate in modo da causare problemi se non ripulite e (2) l'oggetto ha le informazioni necessarie per eseguire tale pulizia ed è responsabile per averlo fatto.
Sebbene molti tipi di risorse non gestite siano fortemente associati a vari tipi di entità del sistema operativo (file, handle GDI, blocchi di memoria allocati, ecc.) Non esiste un singolo tipo di entità che è condivisa da tutti tranne la responsabilità di pulire. In genere, se un oggetto ha la responsabilità di eseguire la pulizia, avrà un metodo Dispose che gli ordina di eseguire tutta la pulizia di cui è responsabile.
In alcuni casi, gli oggetti tengono conto della possibilità che possano essere abbandonati senza che nessuno abbia prima chiamato Dispose. Il GC consente agli oggetti di richiedere la notifica di essere stati abbandonati (chiamando una routine chiamata Finalizza) e gli oggetti possono utilizzare questa notifica per eseguire la pulizia da soli.
Termini come "risorsa gestita" e "risorsa non gestita" sono, purtroppo, usati da persone diverse per indicare cose diverse; francamente penso che sia più utile pensare in termini di oggetti come non avere alcuna responsabilità per la pulizia, avere una responsabilità per la pulizia di cui ci si occuperà solo se si chiama Dispose o avere una responsabilità di pulizia che dovrebbe essere curata tramite Dispose, ma che può essere curato anche da Finalize.
La differenza fondamentale tra una risorsa gestita e non gestita è che il garbage collector conosce tutte le risorse gestite, a un certo punto il GC arriverà e ripulirà tutta la memoria e le risorse associate a un oggetto gestito. Il GC non è a conoscenza di risorse non gestite, come file, stream e handle, quindi se non li ripulisci esplicitamente nel tuo codice, finirai con perdite di memoria e risorse bloccate.
Rubato da qui , sentiti libero di leggere l'intero post.
Qualsiasi risorsa per la quale è allocata la memoria nell'heap gestito .NET è una risorsa gestita. CLR è completamente consapevole di questo tipo di memoria e farà di tutto per assicurarsi che non rimanga orfano. Qualsiasi altra cosa non è gestita. Ad esempio, interagendo con COM, è possibile creare oggetti nello spazio di memoria dei processi, ma CLR non se ne occuperà. In questo caso l'oggetto gestito che effettua chiamate attraverso la lavanderia gestita dovrebbe essere responsabile di qualsiasi cosa al di là di esso.
Cerchiamo innanzitutto di capire come venivano eseguiti i programmi VB6 o C ++ (applicazioni non Dotnet). Sappiamo che i computer comprendono solo il codice a livello di macchina. Il codice a livello di macchina è anche chiamato come codice nativo o binario. Quindi, quando eseguiamo un programma VB6 o C ++, il rispettivo compilatore del linguaggio, compila il rispettivo codice sorgente del linguaggio in codice nativo, che può quindi essere compreso dal sistema operativo e dall'hardware sottostanti.
Il codice nativo (Unmanaged Code) è specifico (nativo) per il sistema operativo su cui viene generato. Se prendi questo codice nativo compilato e provi a eseguirlo su un altro sistema operativo, fallirà. Quindi il problema con questo stile di esecuzione del programma è che non è portabile da una piattaforma all'altra.
Cerchiamo ora di capire come viene eseguito un programma .Net. Usando dotnet possiamo creare diversi tipi di applicazioni. Alcuni dei tipi più comuni di applicazioni .NET includono applicazioni Web, Windows, console e mobili. Indipendentemente dal tipo di applicazione, quando si esegue un'applicazione .NET si verifica quanto segue
L'applicazione .NET viene compilata in Intermediate language (IL). IL è anche indicato come Common Intermediate language (CIL) e Microsoft Intermediate language (MSIL). Entrambe le applicazioni .NET e non .NET generano un assembly. Le assemblee hanno un'estensione di .DLL o .EXE. Ad esempio, se si compila un'applicazione Windows o Console, si ottiene un .EXE, dove come quando compiliamo un progetto di libreria Web o Class otteniamo un .DLL. La differenza tra un assembly .NET e NON .NET è che, DOTNET Assembly è in formato di lingua intermedio, mentre come assembly NON DOTNET è in formato di codice nativo.
Le applicazioni NON DOTNET possono essere eseguite direttamente sul sistema operativo, mentre le applicazioni DOTNET vengono eseguite su un ambiente virtuale chiamato Common Language Runtime (CLR). CLR contiene un componente chiamato Just In-Time Compiler (JIT), che convertirà la lingua intermedia in codice nativo che il sistema operativo sottostante può comprendere.
Quindi, in .NET l'esecuzione dell'applicazione consiste in 2 passaggi 1. Compilatore di lingue, compila il codice sorgente in Intermediate Language (IL) 2. Il compilatore JIT in CLR converte, l'IL in codice nativo che può quindi essere eseguito sul sistema operativo sottostante .
Poiché un assembly .NET è in formato Intermedaite Language e non in codice nativo, gli assembly .NET sono portabili su qualsiasi piattaforma, purché la piattaforma di destinazione abbia Common Language Runtime (CLR). Il CLR della piattaforma di destinazione converte la lingua intermodita in codice nativo che può essere compreso dal sistema operativo sottostante. Intermediate Languge è anche chiamato come codice gestito. Questo perché CLR gestisce il codice che viene eseguito al suo interno. Ad esempio, in un programma VB6, lo sviluppatore è responsabile della disallocazione della memoria consumata da un oggetto. Se un programmatore dimentica di disallocare la memoria, potremmo incorrere in eccezioni difficili da eliminare. D'altra parte un programmatore .NET non deve preoccuparsi di disallocare la memoria consumata da un oggetto. La gestione automatica della memoria, nota anche come raccolta dei rifiuti, è fornita da CLR. A parte, dalla raccolta dei rifiuti, ci sono molti altri vantaggi forniti dal CLR, di cui parleremo in una sessione successiva. Poiché, CLR gestisce ed esegue l'Intermediate Language, esso (IL) viene anche chiamato come codice gestito.
.NET supporta diversi linguaggi di programmazione come C #, VB, J # e C ++. C #, VB e J # possono generare solo codice gestito (IL), dove C ++ può generare sia codice gestito (IL) che codice non gestito (codice nativo).
Il codice nativo non viene memorizzato in modo permanente da nessuna parte, dopo aver chiuso il programma il codice nativo viene eliminato. Quando eseguiamo nuovamente il programma, il codice nativo viene nuovamente generato.
Il programma .NET è simile all'esecuzione del programma java. In java abbiamo codici byte e JVM (Java Virtual Machine), dove come in .NET abbiamo Intermediate Language e CLR (Common Language Runtime)
Questo è fornito da questo link: è un ottimo tutor. http://csharp-video-tutorials.blogspot.in/2012/07/net-program-execution-part-1.html