Cosa si intende per risorse "gestite" e "non gestite" in .NET?


Risposte:


80

Il termine "risorsa non gestita" viene solitamente utilizzato per descrivere qualcosa che non è direttamente sotto il controllo del garbage collector . Ad esempio, se si apre una connessione a un server di database, verranno utilizzate le risorse sul server (per mantenere la connessione) e possibilmente altre risorse non.net sulla macchina client, se il provider non è scritto interamente in codice gestito.

Questo è il motivo per cui, per qualcosa come una connessione a un database, si consiglia di scrivere il codice in questo modo:

using (var connection = new SqlConnection("connection_string_here"))
{
    // Code to use connection here
}

Poiché ciò garantisce che .Dispose()venga chiamato sull'oggetto connessione, assicurando che tutte le risorse non gestite vengano ripulite.


20
Lo chiarirei leggermente: una "risorsa non gestita" è qualcosa che il garbage-collector non saprà come ripulire dopo se viene abbandonata. La sottoscrizione di un oggetto di breve durata a un evento da un oggetto di lunga durata, ad esempio, sarebbe una risorsa non gestita anche se entrambi gli oggetti sono sotto il controllo del garbage-collector, poiché il GC non avrà modo di sapere che l'abbonamento dovrebbe essere scartato se l'abbonato viene abbandonato ma l'editore no. Se un numero illimitato di abbonati potesse essere creato e abbandonato durante la vita dell'editore, ciò causerebbe una perdita di memoria.
supercat

12
Aggiungendo un po 'più di chiarezza: SqlConnection (o FileStream, ecc.) Sono risorse gestite che utilizzano internamente risorse non gestite di cui GC non è a conoscenza.
jimvfr

2
jimvfr ha ragione, SqlConnection è un esempio di risorse gestite. Un esempio di risorse non gestite è quando dobbiamo allocare memoria dalla memoria non gestita usando il metodo Marshal.AllocHGlobal () è una risorsa non gestita in questo caso la best practice è usare un distruttore (~ ctor) e chiamare Marshal.FreeHGlobal () per liberare questa memoria.
Ygor Thomaz

puoi fornire un esempio per le risorse gestite e non gestite.
Radha Manohar

32

Le risorse gestite sono quelle che sono puro codice .NET e gestite dal runtime e sono sotto il suo diretto controllo.

Le risorse non gestite sono quelle che non lo sono. File handle, memoria bloccata, oggetti COM, connessioni al database ecc.


13

Nella sezione Domande e risposte Cosa sono le risorse non gestite? 1 , Bruce Wood ha pubblicato quanto segue:

Penso ai termini "gestito" e "non gestito" in questo modo:

"Gestito" si riferisce a qualsiasi cosa all'interno della sandbox .NET. Ciò include tutte le classi .NET Framework.

"Unmanaged" si riferisce alla natura selvaggia al di fuori della sandbox .NET. Ciò include tutto ciò che viene restituito tramite chiamate alle funzioni API Win32.

Se non chiami mai una funzione API Win32 e non recuperi mai alcun oggetto "handle" Win32, non stai mantenendo alcuna risorsa non gestita. I file e i flussi aperti tramite i metodi di classe .NET Framework sono tutti wrapper gestiti.

Commento: potresti non tenere direttamente una risorsa non gestita . Tuttavia, potresti tenere una risorsa non gestita indirettamente tramite una "classe wrapper" gestita come System.IO.FileStream . Una tale classe wrapper implementa comunemente IDisposable (direttamente o tramite ereditarietà).

... molti oggetti gestiti (.NET Framework) contengono risorse non gestite al loro interno, e probabilmente vorrai Dispose () di esse il prima possibile, o almeno offrire ai tuoi chiamanti l'opportunità di farlo. È qui che entra in gioco la scrittura del proprio metodo Dispose (). Essenzialmente, l'implementazione di IDisposable () fa due cose per te:

  1. Ti consente di sbarazzarti di tutte le risorse che hai preso direttamente dal sistema operativo dietro le spalle di .NET (risorse non gestite).

  2. Consente a te e ai tuoi chiamanti di rilasciare pesanti oggetti .NET / oggetti .NET che tengono preziose risorse nelle loro piccole mani sporche che voi oi vostri chiamanti desiderate rilasciare ora .

Commento: implementando IDisposablee quindi fornendo un Dispose()metodo, si consente a un utente della propria classe di rilasciare in modo deterministico tutte le risorse non gestite detenute da un'istanza della propria classe.


1 Link originariamente condiviso nella risposta di Sachin Shanbhag . Materiale citato datato 2005-11-17. Nota che ho leggermente modificato il contenuto citato.


5

La differenza fondamentale tra una risorsa gestita e una non gestita è che il garbage collector conosce tutte le risorse gestite, a un certo punto il GC arriverà e pulirà tutta la memoria e le risorse associate a un oggetto gestito. Il GC non è a conoscenza delle risorse non gestite, come file, flusso e handle, quindi se non le pulisci esplicitamente nel codice, ti ritroverai con perdite di memoria e risorse bloccate.

Per maggiori dettagli - http://bytes.com/topic/c-sharp/answers/276059-what-unmanaged-resources


1
"L'idea alla base dell'interfaccia IDisposable è quella di consentire di ripulire le risorse in modo deterministico e di ripulire le risorse non gestite." Fantastico!
zionpi

0

Le risorse gestite sono risorse che possono essere liberate dal Garbage Collector e le risorse non gestite non possono essere liberate dal Garbage Collector per questo scopo è richiesto il distruttore.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.