IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Framework .NET Discussion :

objets gérés par le CLR et méthodes du garbage collector


Sujet :

Framework .NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    988
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 988
    Par défaut objets gérés par le CLR et méthodes du garbage collector
    Bonjour,

    Normalement pour les objets gérés par le CLR, le CLR gère l'allocation de mémoire pour ces objets .

    Mais pour les objets non gérés par le CLR (ex: connexion Bases de donénes, connexion réseau ou COM), il est nécessaire de leur allouer manuellement de la mémoire.

    Cependant, pour créer une nouvelle connexion à une base de données, on peut créer une classe connexion dans laquelle on crée un variable qui contiendra la chaine de connexion.

    Puis on pourra ensuite instancier cette classe.

    La connexion devient-elle alors gérée par le CLR ou pas ?

    Car je n'ai pas constaté que j'alloue moi même de la mêmoire pour gérer une connexion de base de données.

    Par ailleurs, concernant le processus de destruction d'un objet , je lis que le garbage collector procède en plusieurs étapes:

    1-les objets situés sur le heap sont marqués morts "jusqu'à preuve du contraire"

    2-les objets références sont marqués vivants

    3-les objets non vivants sont déplacés dans la zone nommée "freachabale queue".

    4-on défragmente le heap en faisant migrer les objets qui s'y trouvent vers le bas du heap

    5-on met à jour les pointeurs vers les objets du heap puisqu'ils ont été déplacés

    6-le processus de finalization commence

    Pour ce qui est de l'étape n°3, Il est ajouté que le garbage collector vérifie que les objets morts aient une méthode destructor.

    Je ne comprends pourquoi existe cette vérification puisque normalement les objets que gère le garbage collector possèdent tous une méthode destructor.

    Seuls les objets non gérés par le garbage collector n'en n'ont pas et il faut leur en ajouter un.

    Autre question, la freachable queue est-elle située sur le heap ou pas?

    Par ailleurs, les méthodes Collect(), WaitForPendingFinalizers, SupressFinalize(), ReRegisterForFinalize(), AddMemoryPressure(), RemoveMemoryPressure() s'appliquent normalement aux objets qui sont gérés par le garbage collector mais qui nécessitent une intervention particulière.

    Cependant ces méthodes s'appliquent elles également aux objets qui ne sont pas gérés par le Garbage collector et pour lesquels on souhaite executer le processus de nettoyage de la mémoire , tout comme pour les autres objets gérés automatiquement par le Garbage Collector.

    Concernant les méthodes AddMemoryPressure et RemoveMemoryPressure, s'appliquent elles bien aux objets qui ne sont pas gérés par le Garbage collector, pour leur allouer ou de la mémoire manuellement ou en récupérer.

    Merci beaucoup de votre réponse sur tous ces points.

    Cordialement

    curieuse_prog

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par new_wave Voir le message
    Mais pour les objets non gérés par le CLR (ex: connexion Bases de donénes, connexion réseau ou COM), il est nécessaire de leur allouer manuellement de la mémoire.
    Ah bon ? Je n'ai jamais alloué manuellement de la mémoire pour me connecter à une base de données...

    Citation Envoyé par new_wave Voir le message
    Cependant, pour créer une nouvelle connexion à une base de données, on peut créer une classe connexion dans laquelle on crée un variable qui contiendra la chaine de connexion.

    Puis on pourra ensuite instancier cette classe.

    La connexion devient-elle alors gérée par le CLR ou pas ?
    Ni plus ni moins qu'avant de créer ta classe connexion
    La connexion elle-même peut être non managée, mais en pratique les objets que tu utilises pour manipuler cette connexion sont managés (par exemple une instance de SqlConnection est gérée par le GC comme n'importe quel objet .NET)


    Citation Envoyé par new_wave Voir le message
    Car je n'ai pas constaté que j'alloue moi même de la mêmoire pour gérer une connexion de base de données.
    Non, parce que tu n'as pas besoin de le faire. C'est fait si nécessaire par des objets qui s'occupent de gérer la connexion à la DB, par exemple en appelant des API non managées. La classe SqlConnection, par exemple, est juste un wrapper qui masque le mécanisme réel de connexion à la base de données ; il est possible qu'il y ait à l'intérieur des allocations mémoire, notamment s'il y a des interactions avec du code natif, mais ça ne te concerne pas : de ton point de vue, c'est un objet .NET comme un autre.

    Citation Envoyé par new_wave Voir le message
    Je ne comprends pourquoi existe cette vérification puisque normalement les objets que gère le garbage collector possèdent tous une méthode destructor.

    Seuls les objets non gérés par le garbage collector n'en n'ont pas et il faut leur en ajouter un.
    Ah bon ? Je ne sais pas où tu as vu ça. La grande majorité des classes .NET n'ont pas de destructeur... Tu peux en implémenter un si nécessaire, mais ce n'est pas obligatoire
    Voir MSDN: http://msdn.microsoft.com/fr-fr/library/66x5fx1b.aspx

    Citation Envoyé par new_wave Voir le message
    Autre question, la freachable queue est-elle située sur le heap ou pas?
    Aucune idée, mais pourquoi te poses-tu cette question ? Je programme en .NET depuis 10 ou 12 ans, je connais cette plateforme de façon très approfondie, et je n'ai jamais eu besoin de savoir ça... Est-ce que cette information aura une influence sur le code que tu écriras ? Ça m'étonnerait...

    Citation Envoyé par new_wave Voir le message
    Par ailleurs, les méthodes Collect(), WaitForPendingFinalizers, SupressFinalize(), ReRegisterForFinalize(), AddMemoryPressure(), RemoveMemoryPressure() s'appliquent normalement aux objets qui sont gérés par le garbage collector mais qui nécessitent une intervention particulière.

    Cependant ces méthodes s'appliquent elles également aux objets qui ne sont pas gérés par le Garbage collector et pour lesquels on souhaite executer le processus de nettoyage de la mémoire , tout comme pour les autres objets gérés automatiquement par le Garbage Collector.

    Concernant les méthodes AddMemoryPressure et RemoveMemoryPressure, s'appliquent elles bien aux objets qui ne sont pas gérés par le Garbage collector, pour leur allouer ou de la mémoire manuellement ou en récupérer.
    Euh... AddMemoryPressure ne sert pas à allouer de la mémoire. Ca sert simplement à prévenir le GC d'une allocation de mémoire non gérée. Il y a 99.99% de chances que tu n'aies jamais besoin d'appeler cette méthode.

    Pour le reste, d'une manière générale, tu n'as quasiment jamais besoin d'interagir avec le Garbage Collector. La plupart des gens qui le font, le font à mauvais escient parce qu'ils ne comprennent pas bien comment ça fonctionne. A moins d'avoir une excellente raison de le faire et d'être un expert du GC, laisse le faire son boulot tranquillement, il s'en sort très bien tout seul

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    988
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 988
    Par défaut objets gérés et non gérés par le CLR
    Bonjour et merci de ta réponse.

    Je reprends quelques unes de tes réponses

    Ah bon ? Je ne sais pas où tu as vu ça. La grande majorité des classes .NET n'ont pas de destructeur... Tu peux en implémenter un si nécessaire, mais ce n'est pas obligatoire
    D'après ce que j'ai compris, dès qu'un objet ne possède plus de référence sur la pile, il devient candidat à la destruction c'est à dire à l'appel de la méthode Finalize(après passage dans la freachable queue).

    Quand il est écrit que "que le garbage collector vérifie que les objets morts aient une méthode destructor."pour l'étape n°3 du processus de destruction d'un objet , que cela signifie-t-il exactement alors:qu' il vérifie qu'il peut bien appeler la méthode Finalize pour ces objets?

    Tu écris également
    AddMemoryPressure ne sert pas à allouer de la mémoire. Ca sert simplement à prévenir le GC d'une allocation de mémoire non gérée. Il y a 99.99% de chances que tu n'aies jamais besoin d'appeler cette méthode.
    D'après ce que j'ai compris cette méthode permet d'allouer de la mémoire non gérée.
    Allouer de la mémoire non gérée signifie-t-il bien allouer de la mémoire pour des objets non gérés par le CLR?
    Si c'est le cas, pourquoi n'aurait-on pas besoin d'allouer de la mémoire pour ces objets?

    Merci encore beaucoup de tes réponses.
    Cela m'aide à voir plus clair dans toutes ces notions.

    Cordialement.

    new_wave

    Je te remercie de ta réponse sur ce point

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Je te conseille de jeter un coup d'oeil à cet article, qui contient beaucoup d'infos utiles sur le sujet :
    http://msdn.microsoft.com/en-us/library/0s71x931.aspx

    Citation Envoyé par new_wave Voir le message
    D'après ce que j'ai compris, dès qu'un objet ne possède plus de référence sur la pile, il devient candidat à la destruction c'est à dire à l'appel de la méthode Finalize(après passage dans la freachable queue).
    En gros, soit l'objet a un finaliseur (i.e. il redéfinit la méthode Finalize, ce qui en C# se fait en déclarant un destructeur), soit non.
    S'il n'en a pas, la mémoire (managée) utilisée par l'objet est juste récupérée
    S'il en a un, il survit un peu plus longtemps : il est ajoutée à une file de finalisation, qui appellera la méthode Finalize. Une fois la méthode Finalize appelée, la mémoire de l'objet est récupérée.

    Citation Envoyé par new_wave Voir le message
    Quand il est écrit que "que le garbage collector vérifie que les objets morts aient une méthode destructor."pour l'étape n°3 du processus de destruction d'un objet , que cela signifie-t-il exactement alors:qu' il vérifie qu'il peut bien appeler la méthode Finalize pour ces objets?
    Il vérifie si la méthode Finalize est redéfinie (overriden)

    Citation Envoyé par new_wave Voir le message
    D'après ce que j'ai compris cette méthode permet d'allouer de la mémoire non gérée.
    Non. Lis la doc :
    Informs the runtime of a large allocation of unmanaged memory that should be taken into account when scheduling garbage collection.
    En gros, le GC ne sait pas ce qui se passe dans la mémoire non gérée (puisqu'il ne la gère pas), mais s'il y a une grosse allocation dans la mémoire non gérée, c'est une info utile pour le GC, car il peut en tenir compte pour retarder ou avancer la collecte des objets morts. AddMemoryPressure sert juste à fournir cette info au GC.

    Citation Envoyé par new_wave Voir le message
    Allouer de la mémoire non gérée signifie-t-il bien allouer de la mémoire pour des objets non gérés par le CLR?
    Ca signifie allouer de la mémoire pour n'importe quoi qui n'est pas géré par le CLR, pas forcément des objets. Typiquement, quand tu interagis avec du code natif en C, c'est de la mémoire qui va contenir des tableaux, des chaines de caractères, etc (le langage C n'a pas de notion d'objet de toute façon)

    Citation Envoyé par new_wave Voir le message
    Si c'est le cas, pourquoi n'aurait-on pas besoin d'allouer de la mémoire pour ces objets?
    Je n'ai pas dit que tu n'avais pas besoin d'allouer de la mémoire, j'ai dit que tu n'avais pas besoin d'appeler AddMemoryPressure (qui ne sert pas à allouer de la mémoire) .

  5. #5
    Membre éclairé

    Profil pro
    Chef de Projet / Développeur
    Inscrit en
    Juin 2002
    Messages
    618
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de Projet / Développeur
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2002
    Messages : 618
    Par défaut
    Lorsqu'une classe fait appel à des ressources non managées, il ne faut pas gérer le nettoyage de ces ressources dans le destructeur, mais rendre la classe disposable et le gérer dans la méthode Dispose();

    Si tu encapsules dans ta classe une connexion à une base de donnée, si l'objet n'est plus référencé il va être détruit. Oui, mais quand ?
    Tu n'en sais rien !

    Si la fermeture de la connexion et le nettoyage mémoire est fait dans le destructeur, il peut se passer un certain moment entre l'éligibilité à la destruction et la destruction effective (et donc la clôture effective de la connexion et/ou le nettoyage effective de la mémoire - d'où, par exemple, des connexions fantômes liés à des objets libérés, mais pas encore détruits).

    D'où l'intérêt du Dispose, qui est appelé par le destructeur, mais qui peut aussi être appelé manuellement. ( il faut d'ailleurs penser à gérer un flag, pour que le dispose n'exécute pas son code 2 fois : une lors de l'appel manuel, puis une seconde fois lors de l'appel par le destructeur au moment du garbage collector).

    Le mieux est alors d'utiliser son objet au sein d'une clause using.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    using( CMaClasse instance = new CMaClasse())
    {
         instance.ceci();
         instance.cela();
    }
    // Ici le dispose a forcement été appelé
    // Les ressources non managées ont été nettoyé.
    // et la limitation de la porté de la variable, fait que je ne peux plus 
    // référencer l'objet.
    // Peu importe quand l'objet sera détruit
    Ca correspond en gros à

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    CMaClasse instance = new CMaClasse();
    try
    {
         instance.ceci();
         instance.cela();
    }
    finally
    {
         instance.Dispose();
    }
    Le soucis de cette dernière construction, c'est que, du point de vue du compilateur, je peux encore faire un appel à instance après le finally, alors que dans la réalité l'objet n'est plus utilisable puisqu'il a nettoyé ses ressources internes.

    D'où l'intérêt du using() { }, qui limite la porté de la variable.

    Si l'utilisateur de la classe oublie d'utiliser le using (ou d'appeler le Dispose), pas de soucis : le destructeur s'en chargera. Par contre l’utilisateur averti pourra manuellement libérer les ressources dès que possible, sans attendre le GC.

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    988
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 988
    Par défaut méthode Dispose
    Merci beaucoup de ces informations.

    Je commence à y voir plus clair dans tout cela.

    new_wave

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    988
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 988
    Par défaut
    Bonjour,

    tu écris

    En gros, soit l'objet a un finaliseur (i.e. il redéfinit la méthode Finalize, ce qui en C# se fait en déclarant un destructeur), soit non.
    S'il n'en a pas, la mémoire (managée) utilisée par l'objet est juste récupérée
    S'il en a un, il survit un peu plus longtemps : il est ajoutée à une file de finalisation, qui appellera la méthode Finalize. Une fois la méthode Finalize appelée, la mémoire de l'objet est récupérée.
    puis j'écris
    Quand il est écrit que "que le garbage collector vérifie que les objets morts aient une méthode destructor."pour l'étape n°3 du processus de destruction d'un objet , que cela signifie-t-il exactement alors:qu' il vérifie qu'il peut bien appeler la méthode Finalize pour ces objets?
    tu réponds alors
    Il vérifie si la méthode Finalize est redéfinie (overriden)

    Bien c'est compris.

    Tu dis que quand un objet possède un destructeur
    il est ajouté à une file de finalisation, qui appellera la méthode Finalize.

    La file de Finalization , est ce bien la freachable queue.
    Est-il exact que c'est le processus de garbage collection qui finalement execute la méthode Finalize pour ces objets

    Te remerciant de ta réponse,

    Cordialement.

    new_wave

  8. #8
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par new_wave Voir le message
    La file de Finalization , est ce bien la freachable queue.
    En fait je n'avais jamais vu ce terme de "freachable queue" avant que tu en parles. Mais en cherchant sur le net, non, ce n'est apparemment pas la même chose... D'ailleurs ma compréhension du processus n'était pas tout à fait exacte apparemment

    En gros, si un objet qui a un finaliseur, un pointeur vers cet objet est mis dans la Finalization queue (dès sa création, pas lors de sa destruction).
    Quand la garbage collection se produit, pour chaque objet identifié comme "déchets" (garbage), le GC cherche s'il y a un pointeur vers cet objet dans la Finalization queue. Si c'est le cas, il est retiré de la finalization queue et ajouté à la freachable queue. La freachable queue est traitée par un autre thread qui appelle Finalize sur chaque objet avant de le retirer. Une fois que c'est fait, la mémoire de l'objet peut être récupérée.

    cf. cet article qui explique ça assez bien (en anglais)

    Citation Envoyé par new_wave Voir le message
    Est-il exact que c'est le processus de garbage collection qui finalement execute la méthode Finalize pour ces objets
    La processus de garbage collection au sens large, oui, mais pas la partie qui s'occupe d'identifier les objets à détruire. C'est un traitement séparé

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [MySQL] Tableau d'objets retourné par méthode de select multiple MySQL
    Par VisualagePacMan dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 19/12/2011, 10h18
  2. objet retourné par une méthode
    Par wafiwafi dans le forum Général Java
    Réponses: 4
    Dernier message: 17/08/2011, 23h37
  3. [Framework] Injecter des objets non gérés par Spring
    Par elix63 dans le forum Spring
    Réponses: 1
    Dernier message: 21/07/2009, 12h51
  4. Réponses: 1
    Dernier message: 09/06/2008, 16h32
  5. Réponses: 9
    Dernier message: 23/02/2004, 19h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo