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

C# Discussion :

Libérer les ressouces en C#


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Août 2004
    Messages
    51
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 51
    Par défaut Libérer les ressouces en C#
    Bonjour,

    Je débute en C#, bien que je connaisse et pratique d'autres langages.

    J'ai tendance à vouloir dés-instancier les ressources et object en appelant la méthode Dispose() et en mettant mes variables à null, mais je ne retrouve pas cette manière de coder en regardant les exemples de code ici ou là.

    Je me pose donc une question, ai je raison de faire cela ou c'est complètement inutile voir générateur de bug ???

    Merci pour votre aide…

  2. #2
    Rédacteur
    Avatar de SaumonAgile
    Homme Profil pro
    Team leader
    Inscrit en
    Avril 2007
    Messages
    4 028
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Team leader
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2007
    Messages : 4 028
    Par défaut
    Ce n'est pas une mauvaise pratique d'appeler Dispose sur les objets implémentant IDisposable, au contraire. Cela facilite le travail du garbage collector.
    Besoin d'un MessageBox amélioré ? InformationBox pour .NET 1.1, 2.0, 3.0, 3.5, 4.0 sous license Apache 2.0.

    Bonnes pratiques pour les accès aux données
    Débogage efficace en .NET
    LINQ to Objects : l'envers du décor

    Mon profil LinkedIn - MCT - MCPD WinForms - MCTS Applications Distribuées - MCTS WCF - MCTS WCF 4.0 - MCTS SQL Server 2008, Database Development - Mon blog - Twitter

  3. #3
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 198
    Par défaut
    les classes manipulant des objets non managés (appartenant à l'OS par exemple, donc que .net n'a pas accès à l'emplacement mémoire de ces objets) implémentent la méthode dispose qui détruit ces objets en question (image, base de données etc...)

    quand une variable est hors de portée (par exemple une sub se fini, tous les varaibles créées dans cette sub sont mises à null, les objets restants dans leur espace mémoire quand meme)

    une instance mise à null met à null toutes ses variables de la meme manière

    le garbage collector cherche les objets non référencés par quelqu'un d'autre
    il appelle la méthode finalize sur ces objets (pour les objets implémentant la méthode dispose, finalize appelle la méthode dispose)
    puis il supprime l'objet de l'emplacement mémoire

    la mémoire est donc libérer toute seule par le garbage collector et on est pas obligé de se poser la question de comment marche la gestion de la mémoire

    par contre il est recommandé d'appeler dispose quand on a plus besoin d'un objet, ca vide la partie non managé de la mémoire tout de suite au moins (using/end using est pas mal pour ca)

    le garbage collector fait pas forcément le ménage souvent ... en général quand l'os lui dit que l'appli commence à etre encombrante au vue de la RAM dispo sur le pc
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  4. #4
    Membre expérimenté
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Par défaut
    Merci a Philorix pour cette excellente question qui a généré des réponses non moins pertinentes

    Etant moi meme un routier du C j'ai aussi l'habitude de faire mes calloc malloc et les free moi meme et de gerer tout ca le plus proprement possible.

    En C# je me demande aussi souvent jusqu'ou on peut ou on doit courrir dans les pieds de la ménagère pour avoir un travail bien fait mais sans trop la bousculer !!

  5. #5
    Membre Expert Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Par défaut
    Citation Envoyé par sperot51 Voir le message
    une instance mise à null met à null toutes ses variables de la meme manière
    Plait-il ? Que veux-tu dire ?

  6. #6
    Membre émérite
    Inscrit en
    Octobre 2006
    Messages
    587
    Détails du profil
    Informations personnelles :
    Âge : 38

    Informations forums :
    Inscription : Octobre 2006
    Messages : 587
    Par défaut
    Citation Envoyé par Philorix Voir le message
    mais je ne retrouve pas cette manière de coder en regardant les exemples de code ici ou là.
    1. L'utilisateur n'a pas besoin d'appeler la méthode Dispose() si le pattern a été correctement mis en place mais c'est au Garbage Collector de l'appeler et ça prends du temps. Il faut désallouer le plus souvent possible pour ne pas obliger le GC à le faire afin de ne pas le surcharger. Le GC a une influence sur les performance ce n'est pas négligeable.

    2. Si tu 'as pas vu d'appel de la méthode Dispose dans du code c'est probablement que le programmeur a utilisé l'instruction suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    using(ObjetImplementantDispose objet = new ObjetImplementantDispose()
    {
       //Instructions
    }
    En fait l'instructions using elle va appeler automatiquement la méthode Dispose en suivant ce principe:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    ObjetImplementantDispose objet = new ObjetImplementantDispose();;
     
    try
    {
     
        //Instructions
    }
    finally
    {
         IDisposable dispose = objet as IDisposable;
         if(dispose != null)
           objet.Dispose();
    }
    D'une manière ou une autre la méthode Dispose sera appelée, ce qui incombe au développeur de l'appeler explicitement.

  7. #7
    Rédacteur
    Avatar de SaumonAgile
    Homme Profil pro
    Team leader
    Inscrit en
    Avril 2007
    Messages
    4 028
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Team leader
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2007
    Messages : 4 028
    Par défaut
    Juste pour réagir à ce que disait harz62, à ma connaissance, le GC n'appelle pas Dispose. Au mieux il demande au finalizer d'appeler la méthode Finalize d'un objet si ce dernier en possède une.
    Par contre Dispose doit être définie de sorte que lorsqu'elle est appelée, elle supprime la nécessité d'appeler cette méthode Finalize.

    En gros, pour résumer :
    - la méthode Finalize (si elle existe) est appelée par le GC de manière non déterministe et sert à libérer les ressources d'un objet.
    - la méthode Dispose est appelée par l'utilisateur pour libérer les ressources de manière déterministe. Quand elle est appelée, elle doit appeler GC.SuppressFinalize(this); pour que le GC n'appelle pas automatiquement la méthode Finalize (vu que les ressources ont déjà été libérées).

    En pratique, la méthode Finalize appelle la méthode Dispose pour factoriser le code. Voici l'implémentation recommandée de IDisposable : http://msdn.microsoft.com/en-us/libr...isposable.aspx
    Besoin d'un MessageBox amélioré ? InformationBox pour .NET 1.1, 2.0, 3.0, 3.5, 4.0 sous license Apache 2.0.

    Bonnes pratiques pour les accès aux données
    Débogage efficace en .NET
    LINQ to Objects : l'envers du décor

    Mon profil LinkedIn - MCT - MCPD WinForms - MCTS Applications Distribuées - MCTS WCF - MCTS WCF 4.0 - MCTS SQL Server 2008, Database Development - Mon blog - Twitter

  8. #8
    Membre émérite
    Inscrit en
    Octobre 2006
    Messages
    587
    Détails du profil
    Informations personnelles :
    Âge : 38

    Informations forums :
    Inscription : Octobre 2006
    Messages : 587
    Par défaut
    Citation Envoyé par SaumonAgile Voir le message
    Juste pour réagir à ce que disait harz62, à ma connaissance, le GC n'appelle pas Dispose. Au mieux il demande au finalizer d'appeler la méthode Finalize d'un objet si ce dernier en possède une.
    Par contre Dispose doit être définie de sorte que lorsqu'elle est appelée, elle supprime la nécessité d'appeler cette méthode Finalize.
    C'est vrai j'ai n'ai pas été assez précis dans mes explications, je vais reprendre le cas ou l'utilisateur n'appelle pas la Méthode Dispose()

    Le GC appelle le finaliseur (comme tu l'a dit) qui est représenté par le code en tant que syntaxe d'un destructeur qui lui même appelle la méthode virtuelle protégée Dispose (c'est une surcharge de la méthode publique, elle prend en paramètre un booléen qui détermine si c'est l'utilisateur ou le finaliseur qui appelle la méthode, elle peut donc réagir en conséquence).

    L'implémentation de la surcharge protégée de Dispose n'est pas obligatoire je pense mais fortement recommandée.

    Pour résumer, il y a 2 méthodes Dispose (c'est cela que je n'ai pas précisé)
    - La méthode protégée virtuelle Dispose avec un paramètre booléen appelée par le finaliseur OU par la méthode publique Dispose.
    - La méthode publique Dispose sans paramètre destinée à être appelée UNIQUEMENT par le développeur.

  9. #9
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 198
    Par défaut
    et tout ceci est écrit noir sur blanc dans msdn ^^


    j'ajouterais aussi que finalize existe sur object donc il est partout, les classes de microsoft ayant un dispose l'appelle dans finalize

    et beaucoup de classes microsoft font gc.supressfinalize(me) dans le constructeur vu que finalize est une méthode couteuse en ressources pour le gc

    Citation Envoyé par Guulh Voir le message
    Plait-il ? Que veux-tu dire ?
    une classe qui comporte des variables
    si j'ai une instance de type classe que je met à null, les variables définies dans cette classe pour cette instance sont mises à null par le framework, certes c'est pas écrit ca dans msdn mais on avait fait quelques tests et puis ca parrait logique, y en a plus besoin ...
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  10. #10
    Membre Expert Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Par défaut
    Citation Envoyé par sperot51 Voir le message
    une classe qui comporte des variables
    si j'ai une instance de type classe que je met à null, les variables définies dans cette classe pour cette instance sont mises à null par le framework, certes c'est pas écrit ca dans msdn mais on avait fait quelques tests et puis ca parrait logique, y en a plus besoin ...
    Non. Quand on affecte une reference a null, on ne fait rien d'autre que mettre une reference a null. L'objet precedemment pointe par cette reference n'est absolument pas impacté, d'autant plus qu'il peut tout a fait avoir d'autres references qui lui pointent dessus. C'est juste que le GC, quand l'envie l'en prendra, supprimera de la memoire tous les objets morts, c'est a dire qui ne sont plus reference par des objets vivants.

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

Discussions similaires

  1. [SWT] Libérer les ressources
    Par soft0613 dans le forum SWT/JFace
    Réponses: 15
    Dernier message: 04/08/2008, 13h32
  2. [Sources] Protéger/Libérer les controls d'un formulaire
    Par bernardmichel dans le forum Contribuez
    Réponses: 6
    Dernier message: 10/09/2007, 22h59
  3. Réponses: 3
    Dernier message: 09/10/2006, 19h22
  4. libérer les epaces Vides
    Par bargou dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 19/12/2005, 17h57
  5. Libérer les ressources lors de la fermeture d'un programme
    Par Heliopraetor dans le forum DirectX
    Réponses: 10
    Dernier message: 14/09/2004, 19h15

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