Je veux en savoir plus sur les ressources non gérées. Quelqu'un peut-il me donner une idée de base?
Je veux en savoir plus sur les ressources non gérées. Quelqu'un peut-il me donner une idée de base?
Réponses:
Ressources gérées signifie essentiellement «mémoire gérée» gérée par le garbage collector. Lorsque vous n'avez plus de références à un objet géré (qui utilise la mémoire gérée), le garbage collector libèrera (éventuellement) cette mémoire pour vous.
Les ressources non gérées sont alors tout ce que le garbage collector ne sait pas. Par exemple:
Normalement, vous souhaitez libérer ces ressources non gérées avant de perdre toutes les références que vous avez à l'objet qui les gère. Vous faites cela en appelant Dispose
cet objet ou (en C #) en utilisant l' using
instruction qui gérera l'appelDispose
pour vous.
Si vous négligez de Dispose
correctement vos ressources non gérées, le garbage collector finira par le gérer pour vous lorsque l'objet contenant cette ressource sera garbage collection (c'est la «finalisation»). Mais comme le garbage collector ne connaît pas les ressources non gérées, il ne peut pas dire à quel point il a besoin de les libérer - il est donc possible que votre programme fonctionne mal ou soit à court de ressources.
Si vous implémentez vous-même une classe qui gère des ressources non managées, c'est à vous de l'implémenter Dispose
et Finalize
correctement.
Dispose
ou d'utiliser using
.
IDisposable
. Si une classe ne mettre en œuvre IDisposable
, vous devez disposer des instances de cette classe avec using
ou Dispose()
lorsque vous avez terminé avec eux. Sur cette base, votre réciproque tient: si une classe implémente IDisposable
, elle contient probablement des ressources non gérées en interne.
Certains utilisateurs classent les fichiers ouverts, les connexions db, la mémoire allouée, les bitmaps, les flux de fichiers, etc. parmi les ressources gérées, d'autres parmi les ressources non gérées. Alors sont-ils gérés ou non gérés?
Mon opinion est que la réponse est plus complexe: lorsque vous ouvrez un fichier dans .NET, vous utilisez probablement une classe .NET intégrée System.IO.File, FileStream ou autre. Comme il s'agit d'une classe .NET normale, elle est gérée. Mais c'est un wrapper, qui à l'intérieur fait le "sale boulot" (communique avec le système d'exploitation en utilisant des dll Win32, appelant des fonctions de bas niveau ou même des instructions d'assembleur) qui ouvre vraiment le fichier. Et c'est ce que .NET ne sait pas, non géré. Mais vous pouvez peut-être ouvrir le fichier vous-même à l'aide des instructions de l'assembleur et contourner les fonctions de fichier .NET. Ensuite, le handle et le fichier ouvert sont des ressources non gérées.
La même chose avec la base de données: si vous utilisez un assemblage de base de données, vous avez des classes comme DbConnection etc., elles sont connues de .NET et gérées. Mais ils encapsulent le "sale boulot", qui n'est pas géré (allouer de la mémoire sur le serveur, établir une connexion avec lui, ...). Si vous n'utilisez pas cette classe wrapper et ouvrez vous-même une socket réseau et communiquez avec votre propre base de données étrange à l'aide de certaines commandes, elle n'est pas gérée.
Ces classes wrapper (File, DbConnection etc.) sont gérées, mais elles utilisent à l'intérieur des ressources non managées de la même manière que vous, si vous n'utilisez pas les wrappers et faites le "sale boulot" par vous-même. Et par conséquent, ces wrappers implémentent les modèles Dispose / Finalize. Il est de leur responsabilité de permettre au programmeur de libérer des ressources non gérées lorsque le wrapper n'est plus nécessaire, et de les libérer lorsque le wrapper est récupéré. L'encapsuleur sera correctement récupéré par garbage collector, mais les ressources non managées à l'intérieur seront collectées à l'aide du modèle Dispose / Finalize.
Si vous n'utilisez pas de classes d'encapsulation .NET ou tierces intégrées et que vous ouvrez des fichiers par des instructions d'assembleur, etc. dans votre classe, ces fichiers ouverts ne sont pas gérés et vous DEVEZ implémenter le modèle de disposition / finalisation. Si vous ne le faites pas, il y aura une fuite de mémoire, une ressource verrouillée à jamais, etc. même si vous ne l'utilisez plus (opération de fichier terminée) ou même après la fin de votre application.
Mais votre responsabilité est également lors de l'utilisation de ces emballages. Pour ceux qui implémentent disposer / finaliser (vous les reconnaissez, qu'ils implémentent IDisposable), implémentez également votre modèle de disposition / finalisation et supprimez même ces wrappers ou donnez-leur le signal de libérer leurs ressources non gérées. Si vous ne le faites pas, les ressources seront libérées après un certain temps indéfini, mais il est propre de le libérer immédiatement (fermez le fichier immédiatement et ne le laissez pas ouvert et bloqué pendant plusieurs minutes / heures au hasard). Ainsi, dans la méthode Dispose de votre classe, vous appelez les méthodes Dispose de tous vos wrappers utilisés.
unmanaged vs managed resources
Une "ressource non gérée" n'est pas une chose, mais une responsabilité. Si un objet possède une ressource non gérée, cela signifie que (1) une entité en dehors de lui a été manipulée d'une manière qui peut causer des problèmes si elle n'est pas nettoyée, et (2) l'objet a les informations nécessaires pour effectuer un tel nettoyage et est responsable pour le faire.
Bien que de nombreux types de ressources non gérées soient très fortement associés à divers types d'entités du système d'exploitation (fichiers, descripteurs GDI, blocs de mémoire alloués, etc.), il n'y a pas un seul type d'entité qui soit partagé par tous, à l'exception de la responsabilité de nettoyer. En règle générale, si un objet a la responsabilité d'effectuer le nettoyage, il aura une méthode Dispose qui lui demande d'effectuer tous les nettoyages dont il est responsable.
Dans certains cas, les objets tiennent compte de la possibilité qu'ils soient abandonnés sans que personne n'ait d'abord appelé Dispose. Le GC permet aux objets de demander une notification indiquant qu'ils ont été abandonnés (en appelant une routine appelée Finalize), et les objets peuvent utiliser cette notification pour effectuer eux-mêmes le nettoyage.
Des termes tels que «ressource gérée» et «ressource non gérée» sont malheureusement utilisés par différentes personnes pour désigner des choses différentes; Je pense franchement qu'il est plus utile de penser en termes d'objets comme n'ayant aucune responsabilité de nettoyage, ayant une responsabilité de nettoyage qui ne sera prise en charge que si Dispose est appelé, ou une responsabilité de nettoyage qui devrait être prise en charge via Dispose, mais qui peut également être pris en charge par Finalize.
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.
Volé d' ici , n'hésitez pas à lire l'article en entier.
Toute ressource pour laquelle de la mémoire est allouée dans le tas managé .NET est une ressource gérée. CLR est parfaitement conscient de ce type de mémoire et fera tout pour s'assurer qu'il ne devienne pas orphelin. Tout le reste n'est pas géré. Par exemple, l'interopérabilité avec COM peut créer des objets dans l'espace mémoire de processus, mais CLR ne s'en chargera pas. Dans ce cas, l'objet géré qui effectue des appels au-delà de la limite gérée doit assumer la responsabilité de tout ce qui se trouve au-delà.
Voyons d'abord comment les programmes VB6 ou C ++ (applications non Dotnet) s'exécutaient. Nous savons que les ordinateurs ne comprennent que le code au niveau de la machine. Le code au niveau de la machine est également appelé code natif ou binaire. Ainsi, lorsque nous exécutons un programme VB6 ou C ++, le compilateur de langage respectif compile le code source du langage respectif en code natif, qui peut ensuite être compris par le système d'exploitation et le matériel sous-jacents.
Le code natif (code non managé) est spécifique (natif) du système d'exploitation sur lequel il est généré. Si vous prenez ce code natif compilé et essayez de l'exécuter sur un autre système d'exploitation, il échouera. Donc le problème avec ce style d'exécution de programme est qu'il n'est pas portable d'une plateforme à une autre.
Voyons maintenant comment s'exécute un programme .Net. En utilisant dotnet, nous pouvons créer différents types d'applications. Quelques-uns des types courants d'applications .NET incluent les applications Web, Windows, console et mobiles. Quel que soit le type de l'application, lorsque vous exécutez une application .NET, les événements suivants se produisent
L'application .NET est compilée en langage intermédiaire (IL). IL est également appelé langage intermédiaire commun (CIL) et langage intermédiaire Microsoft (MSIL). Les applications .NET et non .NET génèrent un assembly. Les assemblys ont une extension .DLL ou .EXE. Par exemple, si vous compilez une application Windows ou Console, vous obtenez un .EXE, alors que lorsque nous compilons un projet de bibliothèque Web ou de classe, nous obtenons un .DLL. La différence entre un assembly .NET et NON .NET est que, l'assembly DOTNET est au format de langage intermédiaire alors que l'assembly NON DOTNET est au format de code natif.
Les applications NON DOTNET peuvent s'exécuter directement sur le système d'exploitation, alors que les applications DOTNET s'exécutent sur un environnement virtuel appelé Common Language Runtime (CLR). CLR contient un composant appelé Just In-Time Compiler (JIT), qui convertira le langage intermédiaire en code natif que le système d'exploitation sous-jacent peut comprendre.
Ainsi, dans .NET, l'exécution de l'application se compose de 2 étapes 1. Le compilateur de langage, compile le code source en langage intermédiaire (IL) 2. Le compilateur JIT dans CLR convertit, l'IL en code natif qui peut ensuite être exécuté sur le système d'exploitation sous-jacent .
Étant donné qu'un assembly .NET est au format Intermedaite Language et non en code natif, les assemblys .NET sont portables sur n'importe quelle plate-forme, à condition que la plate-forme cible dispose du Common Language Runtime (CLR). Le CLR de la plate-forme cible convertit le langage Intermedaite en code natif que le système d'exploitation sous-jacent peut comprendre. L'intermédiaire Languge est également appelé code managé. C'est parce que CLR gère le code qui s'exécute à l'intérieur. Par exemple, dans un programme VB6, le développeur est responsable de la désallocation de la mémoire consommée par un objet. Si un programmeur oublie de désallouer de la mémoire, il se peut que nous ayons du mal à détecter les exceptions de mémoire. D'un autre côté, un programmeur .NET n'a pas à se soucier de la désallocation de la mémoire consommée par un objet. La gestion automatique de la mémoire, également appelée grabage collection, est fournie par CLR. Une part, du garbage collection, il existe plusieurs autres avantages fournis par le CLR, dont nous discuterons dans une session ultérieure. Puisque CLR gère et exécute le langage intermédiaire, il (IL) est également appelé code managé.
.NET prend en charge différents langages de programmation tels que C #, VB, J # et C ++. C #, VB et J # peuvent uniquement générer du code managé (IL), alors que C ++ peut générer à la fois du code managé (IL) et du code non managé (code natif).
Le code natif n'est stocké en permanence nulle part, après la fermeture du programme, le code natif est jetéa. Lorsque nous exécutons à nouveau le programme, le code natif est à nouveau généré.
Le programme .NET est similaire à l'exécution du programme Java. En java, nous avons des codes d'octet et JVM (Java Virtual Machine), où, comme dans .NET, nous avons un langage intermédiaire et CLR (Common Language Runtime)
Ceci est fourni à partir de ce lien - C'est un excellent tuteur. http://csharp-video-tutorials.blogspot.in/2012/07/net-program-execution-part-1.html