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 :

Fuite mémoire? Mais où?


Sujet :

C#

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2002
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2002
    Messages : 101
    Par défaut Fuite mémoire? Mais où?
    Bonjour,

    Voila je travail avec des objets Bitmap et Graphic dans mon projet.
    J'ai réduit mon code pour obtenir ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    Graphics g = Graphics.FromHwnd(this.Handle);
    Bitmap b = new Bitmap(1024,768,g);
     
    pictureBox1.Image = Image.FromHbitmap(b.GetHbitmap());
     
    b.Dispose();
    b = null;
     
    g.Dispose();
    g = null;
    Alors ça ne sert à rien comme ça mais c'est juste pour vous présentez mon problème.

    Ce code est dans un timer, de 200ms (le temps n'a aucune importance), le problème c'est que dans le gestionnaire de tache, je constate que mon programme monte facilement à 200mo de mémoire, et le nombre d'objet GDI augmente sans cesse.

    Je voudrais savoir ce que j'ai oublié? pourquoi je libère bien les objets

    J'ai un doute sur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pictureBox1.Image = Image.FromHbitmap(b.GetHbitmap());
    Mais comment je peux faire?

  2. #2
    Membre éclairé Avatar de ZaaN
    Inscrit en
    Novembre 2005
    Messages
    819
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 819
    Par défaut
    je connais pas le fonctionnemnt exact du GC !

    Mais je sais qu il existe de soft du genre : .NET Memory Profiler 3.1. (full function trial 14 jours)

    a+

  3. #3
    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
    Bonjour,

    Je vois pas trop ce que tu veux faire. A quoi sert l'objet Graphics ?

  4. #4
    Membre éprouvé Avatar de Nikoui
    Inscrit en
    Décembre 2007
    Messages
    119
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Décembre 2007
    Messages : 119
    Par défaut
    Bonjour, et en stockant le résultat de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    IntPtr hBitmap = b.GetHbitmap();
    puis en appelant ensuite avant de quitter un petit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    DeleteObject(hBitmap );
    c'est mieux?

  5. #5
    Expert confirmé
    Avatar de ced600
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Août 2006
    Messages
    3 364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Août 2006
    Messages : 3 364
    Par défaut
    Si mes souvenirs sont bon dispose n'est pas toujours implémenté sur les objets.
    Je crois qu'il faut peut être le surcharger dans ton cas.

  6. #6
    Membre Expert
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 103
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 103
    Par défaut
    Dispose est implanté sur tous les objets du famework ayant trait à manipuler des ressources non managées.

    Comment microsoft pourrait espéré que les développeur le fasse, s'ils ne le faisaient pas eux même

  7. #7
    Expert confirmé
    Avatar de ced600
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Août 2006
    Messages
    3 364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Août 2006
    Messages : 3 364
    Par défaut
    Je confonds peut être avec JAV, mais j'ai un vague souvenir que l'un des deux langages n'implémentent pas toujours le dispose, il propose toujours la méthode mais des fois elle est vide.

  8. #8
    Membre éprouvé Avatar de Nikoui
    Inscrit en
    Décembre 2007
    Messages
    119
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Décembre 2007
    Messages : 119
    Par défaut
    Citation Envoyé par ced600 Voir le message
    il propose toujours la méthode mais des fois elle est vide.
    Mais dans tous les cas, et aussi bien en Java qu'en C#, comment veut tu faire pour implémenter toi même le dispose d'un objet ? (autrement dit, comment libérer les ressources internes d'un objet que tu n'a pas défini ?)

  9. #9
    Membre éprouvé Avatar de Onlava
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    92
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2007
    Messages : 92
    Par défaut
    As tu essayé de voir ce que dit GC.GetTotalMemory(false) ?
    Souvent j'ai l'impression que windows ne comprends pas grand chose à la mémoire managée..

  10. #10
    Expert confirmé
    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
    Par défaut
    Juste en passant :
    GetHbitmap
    Creates a GDI bitmap object from this Bitmap.
    Donc la méthode de Nikoui devrait être bonne.
    FromHbitmap
    Crée un Bitmap à partir d'un handle Windows.
    Et quand est-ce que tu le dispose celui là ?

    Et pour finir, normalement dès qu'un objet dispose d'une méthode Dispose elle sert à quel que chose car il faut explicitement la créer et dériver l'objet de IDisposable. Donc tous les objets qui l'implémentent dans le .NET Framework ont une méthode Dispose qui est non vide (par définition). De toute façon, Microsoft dit clairement qu'un objet avec un Dispose vide n'a pas d'intérêt et qe dans ce cas il ne devrait pas surcharger Disposer ou implémenter IDisposable.

  11. #11
    Expert confirmé
    Avatar de ced600
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Août 2006
    Messages
    3 364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Août 2006
    Messages : 3 364
    Par défaut
    Ok je remballe mes fragments de souvenir, j'ai dit une bétise

  12. #12
    Membre Expert
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 103
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 103
    Par défaut
    non ta pas dit une bétise car sous java... effective cette méthode existe mais elle est 99% du temps vide....
    meme parfois et c'est là que c'est genant sur des classes utilisant des ressources "non managées" (extérieure à java... en gros tout)
    jen ai tristement fait l'expérience... ca ajouté un GC encore plus capricieux que celui de dotnet c'est le ponpon
    mais passons.

    attention à la libération des handles windows... toutefois
    Ici il ne faut le libérer manuellement que dans le cas du Get pas du From, sauf si celui utilisé dans le From est géré par tes soins.

  13. #13
    Expert confirmé
    Avatar de ced600
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Août 2006
    Messages
    3 364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Août 2006
    Messages : 3 364
    Par défaut


    Merci je ne suis pas vieux avant l'age alors

  14. #14
    Membre éprouvé Avatar de Nikoui
    Inscrit en
    Décembre 2007
    Messages
    119
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Décembre 2007
    Messages : 119
    Par défaut
    En fait en Java la méthode Dispose est définie directement dans la classe "racine" Object. Et donc forcément, toutes les classes héritant (comme en C#) de Object, elles ont toutes cette méthode.

    Cela dit je ne vois pas en quoi c'est un problème d'avoir une méthode Dispose définie mais vide...

    Quand au fait qu'une classe ne libère pas les ressources qu'elle devrait libérer, c'est un autre problème (le fait d'avoir ou non une méthode Dispose définie dans une classe mère ne change rien à ça, c'est le développeur qu'il faut changer )

    Concernant le garbage collector, là par contre on est d'accord, celui de C# est une pure merveille à côté de ce que j'ai connu en Java (même si ça c'est amélioré et qu'il n'existe peut être plus de cas de fuite mémoire avérés en Java)

  15. #15
    Expert confirmé
    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
    Par défaut
    Citation Envoyé par Nikoui Voir le message
    Cela dit je ne vois pas en quoi c'est un problème d'avoir une méthode Dispose définie mais vide...
    ça fait que l'objet va rester plus longtemps en mémoire car d'après ce que j'ai lu il faudra deux cycles du GC pour le collecter. Un pour appeler Dispose (mais après, l'objet et toujours en mémoire) et un deuxième pour véritablement le supprimer alors que sans Dispose il est supprimé au premier passage (le même comportement que si on appelle dispose manuellement).

  16. #16
    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
    Citation Envoyé par smyley Voir le message
    ça fait que l'objet va rester plus longtemps en mémoire car d'après ce que j'ai lu il faudra deux cycles du GC pour le collecter. Un pour appeler Dispose (mais après, l'objet et toujours en mémoire) et un deuxième pour véritablement le supprimer alors que sans Dispose il est supprimé au premier passage (le même comportement que si on appelle dispose manuellement).
    Et encore, tu ne parles même pas du finalize qui ressucite l'objet avant de le détruire.
    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

  17. #17
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2002
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2002
    Messages : 101
    Par défaut
    Wouhou merci pour toute vos remarques/réponses

    Le GC.GetTotalMemory(false) me retourne un résultat qui reste autour de 44000. Par contre dans le gestionnaire de tache le nombre d'objet ne fait que d'augmenter et arrivé à 3131 objet, paf l'application explose

    La méthode DeleteObjet vient d'une API?

  18. #18
    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
    Est ce que tu utilises des formulaire affichés avec ShowDialog ?
    Si c'est le cas, il ne faut pas oublier d'appeler Dispose sur le formulaire après l'affichage, sinon la mémoire n'est pas libérée.
    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

  19. #19
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2002
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2002
    Messages : 101
    Par défaut
    Non c'est une application toute simple:

    J'ai le formulaire de base, un timer et un bouton qui va lancer ce timer.

    C'est juste une application de test, car je veux ensuite intégré ce principe dans un plus gros programme, mais si déja à ce niveau le programme monte a 200mo de mémoire.... c'est moche!

  20. #20
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2002
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2002
    Messages : 101
    Par défaut
    Bon je pense avoir réglé mon problème:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     
    if (i != null)
       i.Dispose();
     
    i = Image.FromHbitmap(hBitmap);
     
    pictureBox1.Image = i;
    Avec:
    Comme attribut de ma classe

Discussions similaires

  1. Fuites massive de mémoire! Mais pourquoi? :/
    Par Spidyy dans le forum Débuter
    Réponses: 5
    Dernier message: 15/06/2009, 22h27
  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. [Toujours fuite de mémoire, mais repéré]
    Par Gonath dans le forum C++
    Réponses: 4
    Dernier message: 06/03/2006, 00h01
  4. [SWT]SWT et fuite mémoire(ou pas)
    Par menuge dans le forum SWT/JFace
    Réponses: 2
    Dernier message: 22/06/2004, 21h40
  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