Qu'entend-on par ressources «gérées» ou «non gérées» dans .NET?

Réponses:

80

Le terme «ressource non gérée» est généralement utilisé pour décrire quelque chose qui n'est pas directement sous le contrôle du garbage collector . Par exemple, si vous ouvrez une connexion à un serveur de base de données, cela utilisera des ressources sur le serveur (pour maintenir la connexion) et éventuellement d'autres ressources non -.net sur l'ordinateur client, si le fournisseur n'est pas entièrement écrit en code managé.

C'est pourquoi, pour quelque chose comme une connexion à une base de données, il est recommandé d'écrire votre code ainsi:

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

Comme cela garantit qu'il .Dispose()est appelé sur l'objet de connexion, garantissant que toutes les ressources non gérées sont nettoyées.

Rob
la source
20
Je le clarifierais légèrement: une "ressource non gérée" est quelque chose que le ramasse-miettes ne saura pas nettoyer après si elle est abandonnée. L'abonnement d'un objet de courte durée à un événement à partir d'un objet de longue durée, par exemple, serait une ressource non gérée même si les deux objets sont sous le contrôle du garbage collector, puisque le GC n'aura aucun moyen de savoir que l'abonnement doit être mis au rebut si l'abonné est abandonné, mais pas l'éditeur. Si un nombre illimité d'abonnés pouvait être créé et abandonné pendant la vie de l'éditeur, cela provoquerait une fuite de mémoire.
supercat du
12
Ajout d'un peu plus de clarification: SqlConnection (ou FileStream, etc.) sont des ressources gérées qui utilisent en interne des ressources non gérées dont GC n'a pas connaissance.
jimvfr
2
jimvfr a raison, SqlConnection est un exemple de ressources gérées. Un exemple de ressources non gérées est lorsque nous devons allouer de la mémoire à partir de la mémoire non gérée à l'aide de la méthode Marshal.AllocHGlobal (), c'est une ressource non gérée dans ce cas, la meilleure pratique consiste à utiliser un destructeur (~ ctor) et à appeler Marshal.FreeHGlobal () pour libérer cette mémoire.
Ygor Thomaz
pouvez-vous s'il vous plaît donner un exemple pour les ressources gérées et non gérées.
Radha Manohar
32

Les ressources gérées sont celles qui sont du code .NET pur et qui sont gérées par le runtime et qui sont sous son contrôle direct.

Les ressources non gérées sont celles qui ne le sont pas. Poignées de fichiers, mémoire épinglée, objets COM, connexions de base de données, etc.

Oded
la source
13

Dans les questions-réponses Que sont les ressources non gérées? 1 , Bruce Wood a publié ce qui suit:

Je pense aux termes «géré» et «non géré» de cette façon:

«Géré» fait référence à tout ce qui se trouve dans le bac à sable .NET. Cela inclut toutes les classes .NET Framework.

«Non géré» fait référence à la nature sauvage en dehors du bac à sable .NET. Cela inclut tout ce qui vous est renvoyé via des appels aux fonctions de l'API Win32.

Si vous n'appelez jamais une fonction API Win32 et ne récupérez jamais aucun objet "handle" Win32, vous ne détenez aucune ressource non gérée. Les fichiers et les flux que vous ouvrez via les méthodes de classe .NET Framework sont tous des wrappers gérés.

Commentaire: Vous ne pouvez pas être une ressource non gérée teniez directement . Cependant, vous pouvez détenir une ressource non gérée indirectement via une «classe wrapper» gérée telle que System.IO.FileStream . Une telle classe wrapper implémente généralement IDisposable (soit directement, soit par héritage).

... de nombreux objets gérés (.NET Framework) contiennent des ressources non gérées à l'intérieur, et vous souhaiterez probablement en disposer () dès que possible, ou au moins offrir à vos appelants la possibilité de le faire. C'est là qu'intervient l'écriture de votre propre méthode Dispose (). Essentiellement, l'implémentation de IDisposable () fait deux choses pour vous:

  1. Vous permet de vous débarrasser de toutes les ressources que vous avez récupérées directement du système d'exploitation derrière le dos de .NET (ressources non gérées).

  2. Vous permet, à vous et à vos appelants, de libérer de lourds objets .NET / objets .NET qui détiennent des ressources précieuses dans leurs petites mains sales que vous / vos appelants voulez libérer maintenant .

Commentaire: En implémentant IDisposableet en fournissant ainsi une Dispose()méthode, vous permettez à un utilisateur de votre classe de libérer de manière déterministe toutes les ressources non gérées qui sont détenues par une instance de votre classe.


1 Lien initialement partagé dans la réponse de Sachin Shanbhag . Matériel cité en date du 17/11/2005. Notez que j'ai légèrement copié le contenu cité.

DavidRR
la source
5

La différence fondamentale entre une ressource gérée et non gérée est que le garbage collector connaît toutes les ressources gérées, à un moment donné, le GC viendra nettoyer toute la mémoire et les ressources associées à un objet géré. Le GC ne connaît pas les ressources non gérées, telles que les fichiers, les flux et les descripteurs, donc si vous ne les nettoyez pas explicitement dans votre code, vous vous retrouverez avec des fuites de mémoire et des ressources verrouillées.

Pour plus de détails - http://bytes.com/topic/c-sharp/answers/276059-what-unmanaged-resources

Sachin Shanbhag
la source
1
"L'idée derrière l'interface IDisposable est de vous permettre de nettoyer les ressources de manière déterministe et de nettoyer les ressources non gérées." Génial!
zionpi
0

Les ressources gérées sont des ressources qui peuvent être libérées par le garbage collector et les ressources non gérées ne peuvent pas être libérées par le garbage collector dans ce but, un destructeur est requis.

anil
la source