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 :

Fuite mémoire .NET


Sujet :

Framework .NET

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 29
    Points : 8
    Points
    8
    Par défaut Fuite mémoire .NET
    Bonjour,

    Je sais que il y a déja plusieurs sujet sur les fuites mémoire, mais m'a question est en relation au framework .Net.
    Jvai peut être poser une question idiote mais, est ce qu'il peut y avoir des fuites mémoires en .Net (c#)?
    En utilisant un profiler (Your Kit Profiler 3.0.5 for .net) j'ai pu visualiser le % d'utilisation du GC, qui peut certaines fois atteindre 100%, c grave ?
    En mm temps mon programme charge une grosse structure d'idientifiants.
    Alors je sais pas si je dois revoir mon code ou pas ...

    Merci pour votre aide

  2. #2
    Rédacteur
    Avatar de The_badger_man
    Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2005
    Messages
    2 745
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 745
    Points : 8 538
    Points
    8 538
    Par défaut
    Citation Envoyé par alaks Voir le message
    En mm temps mon programme charge une grosse structure d'idientifiants.
    c'est à dire ?
    Les règles du forum
    Le trio magique : FAQ + Cours + fonction rechercher
    Mes articles
    Pas de questions par messages privés svp

    Software is never finished, only abandoned.

  3. #3
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    Citation Envoyé par alaks Voir le message
    Jvai peut être poser une question idiote mais, est ce qu'il peut y avoir des fuites mémoires en .Net (c#)?
    Oui, par exemple si tu crées des objets infiniment en espérant qu'ils soient collectés par le GC mais en gardant une référence ailleurs genre dans une List, donc ils ne seront jamais collectés et la mémoire utilisée ne fera qu'augmenter ...

  4. #4
    Rédacteur
    Avatar de dev01
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    2 451
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 451
    Points : 6 017
    Points
    6 017
    Par défaut
    Citation Envoyé par smyley Voir le message
    Oui, par exemple si tu crées des objets infiniment en espérant qu'ils soient collectés par le GC mais en gardant une référence ailleurs genre dans une List, donc ils ne seront jamais collectés et la mémoire utilisée ne fera qu'augmenter ...
    ça sens le vécu .

    Pour ce qui est de la fuite mémoire, une autre des causes possible est l'utilisation incorrect de ressources non managé ( IE : PInvoke ) et l'oubli d'appeler Dispose sur les objet qui implémente IDisposable ...
    - MVP C#
    -Tout problème a une solution, le vrai problème est de trouver la solution .....
    - Linux & mono : l'avenir

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 29
    Points : 8
    Points
    8
    Par défaut
    Merci pour vos réponses.

    Quand je parlais d'identifiants je fait allusion en fait à des string (ex: "00011101", ..).
    En fait je rempli plusieurs arbres avec plus millions de string, ces listes me servent de reference pour la comparaison avec des arraylist de string.
    Apres tous ce que vous avait dit, l'interface IDisposable est elle hérité de tous objets ? je voulais utilisai la méthode dispose sur une arraylist mais je l'ai pas trouvé ..

    Dans la piece jointe , le code de liberation mémoire :
    Pièce jointe 28065

    Mon arbre a la structure suivante :
    Pièce jointe 28066

    dois je faire heriter la classe de l'interface IDisposable, destructeur, ...

  6. #6
    Rédacteur
    Avatar de The_badger_man
    Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2005
    Messages
    2 745
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 745
    Points : 8 538
    Points
    8 538
    Par défaut
    Citation Envoyé par alaks Voir le message
    En fait je rempli plusieurs arbres avec plus millions de string
    hum...t'aurais un autre algo ?
    Les règles du forum
    Le trio magique : FAQ + Cours + fonction rechercher
    Mes articles
    Pas de questions par messages privés svp

    Software is never finished, only abandoned.

  7. #7
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    Citation Envoyé par dev01 Voir le message
    ça sens le vécu .



    Citation Envoyé par dev01
    l'oubli d'appeler Dispose sur les objet qui implémente IDisposable ...
    Il n'est pas nécéssaire d'appeler manuellement Dispose, mais c'est préférable (le GC peut le faire automatiquement).

    Citation Envoyé par alaks
    Apres tous ce que vous avait dit, l'interface IDisposable est elle hérité de tous objets ?
    Non

    Citation Envoyé par The_badger_man Voir le message
    hum...t'aurais un autre algo ?
    +1, il y a forcément mieux ...

  8. #8
    Rédacteur
    Avatar de dev01
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    2 451
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 451
    Points : 6 017
    Points
    6 017
    Par défaut
    Citation Envoyé par smyley Voir le message
    Il n'est pas nécéssaire d'appeler manuellement Dispose, mais c'est préférable (le GC peut le faire automatiquement).
    Oui et non. Le problème des ressources non managé et donc de dispose c'est que l'on ne sais jamais si ça va fontionner ou non . Les bests practices sont assez claire la dessus, ou on appelle Dispose() ou on utilise
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    using ( MaRessourceDisposable )
    {
     
    }
    mais on ne laisse pas le garbage collector le faire .
    - MVP C#
    -Tout problème a une solution, le vrai problème est de trouver la solution .....
    - Linux & mono : l'avenir

  9. #9
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 29
    Points : 8
    Points
    8
    Par défaut
    Dans ce cas, je vais me pencher sur l'interface IDisposable, et faire heriter les classes qui en ont besoin

  10. #10
    Rédacteur
    Avatar de Greybird
    Inscrit en
    Juin 2002
    Messages
    673
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 673
    Points : 1 271
    Points
    1 271
    Par défaut
    Citation Envoyé par smyley Voir le message
    Il n'est pas nécessaire d'appeler manuellement Dispose, mais c'est préférable (le GC peut le faire automatiquement).
    Faux, le GC n'appellera jamais Dispose. Au mieux il appellera le finaliseur (méthode Finalize(), créée via la syntaxe d'un destructeur de classe en C#), qui, s'il est bien conçu, appellera lui-même Dispose. Mais ce n'est en aucun cas une obligation d'appeller Dispose dans le finaliseur.
    Dispose est prévu pour faire de la libération de ressources au plus tôt, de manière explicite, et idéalement pour éviter de passer par les finaliseurs qui sont relativements coûteux pour le GC, car ils imposent une deuxième passe sur l'objet.

  11. #11
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    ça doit être lié à ma manière de coder alors
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    class Bidule : IDisposable
    {
     ~Bidule()
     {
       Dispose();
     }
     
     ...
    }
    Je pense que c'est nécéssaire dès que l'on gère des ressources non managés ou qu'il est nécéssaire d'effectuer des actions lorsqu'un objet est détruit ...

  12. #12
    Rédacteur
    Avatar de dev01
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    2 451
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 451
    Points : 6 017
    Points
    6 017
    Par défaut
    Citation Envoyé par smyley Voir le message
    ça doit être lié à ma manière de coder alors
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    class Bidule : IDisposable
    {
     ~Bidule()
     {
       Dispose();
     }
     
     ...
    }
    Je pense que c'est nécéssaire dès que l'on gère des ressources non managés ou qu'il est nécéssaire d'effectuer des actions lorsqu'un objet est détruit ...
    Ton code me pose un problème : L'utilisation des destructeur est déconseillé car ça ralenti le travail du GC ... Or tu l'utilises pour faire une action qui, à mon avis, ne doit pas être faite à la destruction mais bien à la fin de l'utilisation de l'objet. Bref personnellement je supprimerais le destructeur et j'utiliserais la directive using pour être sur que le système appel Dispose
    - MVP C#
    -Tout problème a une solution, le vrai problème est de trouver la solution .....
    - Linux & mono : l'avenir

  13. #13
    Rédacteur
    Avatar de Greybird
    Inscrit en
    Juin 2002
    Messages
    673
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 673
    Points : 1 271
    Points
    1 271
    Par défaut
    Citation Envoyé par dev01 Voir le message
    Ton code me pose un problème : L'utilisation des destructeur est déconseillé car ça ralenti le travail du GC ... Or tu l'utilises pour faire une action qui, à mon avis, ne doit pas être faite à la destruction mais bien à la fin de l'utilisation de l'objet. Bref personnellement je supprimerais le destructeur et j'utiliserais la directive using pour être sur que le système appel Dispose
    En l'état ce code est effectivement un problème, mais appeller Dispose dans le finaliseur est plutôt une bonne pratique, à condition de ne pas le faire n'importe comment.

    Il suffit de se retirer de la file de finalisation dans le dispose. Si on l'appelle explicitement (via un appel direct ou via la fin du bloc using), la finalisation n'a pas lieu, mais si par quelque moyen que ce soit, le dispose n'est pas appelé explicitement, le nettoyage aura lieu au prix du finaliseur.

    cf le MSDN : http://msdn2.microsoft.com/en-us/lib...sfinalize.aspx

  14. #14
    Rédacteur
    Avatar de dev01
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    2 451
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 451
    Points : 6 017
    Points
    6 017
    Par défaut
    Citation Envoyé par Greybird Voir le message
    En l'état ce code est effectivement un problème, mais appeller Dispose dans le finaliseur est plutôt une bonne pratique, à condition de ne pas le faire n'importe comment.

    Il suffit de se retirer de la file de finalisation dans le dispose. Si on l'appelle explicitement (via un appel direct ou via la fin du bloc using), la finalisation n'a pas lieu, mais si par quelque moyen que ce soit, le dispose n'est pas appelé explicitement, le nettoyage aura lieu au prix du finaliseur.

    cf le MSDN : http://msdn2.microsoft.com/en-us/lib...sfinalize.aspx
    j'en prend note
    - MVP C#
    -Tout problème a une solution, le vrai problème est de trouver la solution .....
    - Linux & mono : l'avenir

  15. #15
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Points : 19 434
    Points
    19 434
    Par défaut
    Citation Envoyé par dev01 Voir le message
    Bref personnellement je supprimerais le destructeur et j'utiliserais la directive using pour être sur que le système appel Dispose
    Je me permettrais de rajouter une chose: en tant que développeur, tu connais ton code et tu sais donc que ta classe implémente IDisposable. Tu es donc en mesure de savoir que tu peux appeller Dispose.

    Mais dans le cas où tu travailles avec d'autres développeurs qui ne font pas de bloc using ou qui n'appelle pas Dispose (car ils n'ont pas vu que c'était possible), passer par le destructeur te permet de t'assurer que le Dispose est appelé

  16. #16
    Rédacteur
    Avatar de dev01
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    2 451
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 451
    Points : 6 017
    Points
    6 017
    Par défaut
    Citation Envoyé par Thomas Lebrun Voir le message
    Mais dans le cas où tu travailles avec d'autres développeurs qui ne font pas de bloc using ou qui n'appelle pas Dispose (car ils n'ont pas vu que c'était possible), passer par le destructeur te permet de t'assurer que le Dispose est appelé
    Yep mais je travail avec de bon développeur qui savent lire une documentation que j'ai généré et ils savent donc qu'il faut appeler Dispose sur les objets qu'ils utilisent

    Plus sérieusement, c'est une très bonne remarque, je la rajoute dans mon calepin à bonne remarque
    - MVP C#
    -Tout problème a une solution, le vrai problème est de trouver la solution .....
    - Linux & mono : l'avenir

  17. #17
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    Citation Envoyé par dev01 Voir le message
    Yep mais je travail avec de bon développeur qui savent lire une documentation que j'ai généré et ils savent donc qu'il faut appeler Dispose sur les objets qu'ils utilisent
    ... une parole sage m'est venue à l'idée :
    any attempt to make any system idiot proof will only challenge God to make a better idiot
    Donc il y en aura forcément un qui verra pas

  18. #18
    Membre éprouvé
    Profil pro
    Inscrit en
    Août 2003
    Messages
    835
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2003
    Messages : 835
    Points : 1 046
    Points
    1 046
    Par défaut
    Citation Envoyé par Thomas Lebrun Voir le message
    Je me permettrais de rajouter une chose: en tant que développeur, tu connais ton code et tu sais donc que ta classe implémente IDisposable. Tu es donc en mesure de savoir que tu peux appeller Dispose.

    Mais dans le cas où tu travailles avec d'autres développeurs qui ne font pas de bloc using ou qui n'appelle pas Dispose (car ils n'ont pas vu que c'était possible), passer par le destructeur te permet de t'assurer que le Dispose est appelé
    L'appel du finalizer tu ne le maitrises pas, si tu laisses charge au GC de libérer tes ressources ça peut donner un programme qui semble fonctionner de manière aléatoire. Par exemple si tu encapsules une ressource native limitée, que tu n'appelles pas explicitement dispose et qu'il n'y a pas de pression sur la mémoire alors ta ressource native ne sera jamais libérée et l'appli peut en manquer (alors que si la mémoire est sous pression le GC est appelé et les finalize aussi)... Vaut-il mieux un programme qui "plante" tout le temps en implémentant pas de finalizer et en demandant un appel explicite au dispose (facile à débuguer en cas de pb) ou un programme qui fonctionnera probablement souvent mais avec un risque de plantage aléatoire (plus dur à débuguer) ?

  19. #19
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    Citation Envoyé par Sphax Voir le message
    Par exemple si tu encapsules une ressource native limitée, que tu n'appelles pas explicitement dispose et qu'il n'y a pas de pression sur la mémoire alors ta ressource native ne sera jamais libérée et l'appli peut en manquer
    C'est pour celà qu'on a inventé GC.AddMemoryPressure.

  20. #20
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Points : 19 434
    Points
    19 434
    Par défaut
    Citation Envoyé par dev01 Voir le message
    Plus sérieusement, c'est une très bonne remarque, je la rajoute dans mon calepin à bonne remarque


    Mais bon, je suis assez d'accord avec toi: normalement, on doit toujours lire la doc

Discussions similaires

  1. Fuite mémoire dans application winform .NET 2.0
    Par olysmar dans le forum Framework .NET
    Réponses: 6
    Dernier message: 30/11/2012, 15h41
  2. [tomcat][memoire] java.net.URL et fuite mémoire
    Par Seiya dans le forum Tomcat et TomEE
    Réponses: 6
    Dernier message: 09/03/2009, 10h41
  3. Fuite Mémoire VB.NET
    Par LamInR dans le forum VB.NET
    Réponses: 6
    Dernier message: 11/01/2009, 18h36
  4. [C# .NET 2.0] setTooltips et fuite mémoire
    Par xtream dans le forum Windows Forms
    Réponses: 4
    Dernier message: 05/11/2006, 20h20
  5. [debug] fuites mémoires
    Par tmonjalo dans le forum C
    Réponses: 3
    Dernier message: 28/07/2003, 17h20

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