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

MFC Discussion :

[MFC] Problème de mémoire jamais désallouée


Sujet :

MFC

  1. #1
    Membre confirmé Avatar de nmarf
    Inscrit en
    Mai 2003
    Messages
    92
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 92
    Par défaut [MFC] Problème de mémoire jamais désallouée
    Boujour à tous,

    Voici mon problème :

    Une appli en TCL lancée en tâche de fond écrit des fichiers tif à intervalle régulier. Une appli MFC constamment visible utilise un timer pour afficher les 20 dernières images écrites par le TCL. Un bouton dans cette appli permet dans lancer un autre dont le but est de visualiser toutes les images TIF générées dans une fenêtre scrollable. Voilà pour le contexte.

    Mon appli a été testée seule (cad sans le TCL et l'autre appli en fond) et il n'y a pas de fuites mémoire (à priori, vérifications faites avec le TaskManager et l'exécution en mode Debug).
    Mais maintenant que j'essaie de la lancer avec tout le monde, j'ai l'impression que les désallocation ne fonctionnent plus car la mémoire augmente à chaque nouveau chargement et pire, quand on quitte elle reste allouée

    Comment être sûr que les désallocation se fassent ? J'ai essayé avec des CriticalSections mais sans succés (peut-être m'y suis-je mal pris...).

    :

  2. #2
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    c'est l'application MFC graphique qui ne libere pas la memoire?

  3. #3
    Membre confirmé Avatar de nmarf
    Inscrit en
    Mai 2003
    Messages
    92
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 92
    Par défaut
    Effectivement, ce n'est pas super clair...

    Il semblerait que ce soit dans l'appli MFC qui affiche tous les défauts que se trouve le problème : quand je scroll, la mémoire totale utilisée augmente BIEN QUE la mémoire du process correspondant ne varie pas

  4. #4
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    tu as regardé l'occupation GDI ? (c'est une colonne a rajouter dans le gestionnaire de taches).
    sinon si c'est vraiment du memory leaks lance ton programme en trace debug .
    quand tu fermes l'application tu devrais avoir les traces des alloc non relachés .
    (a condition d'avoir les macros :#define new DEBUG_NEW etc..)


  5. #5
    Membre confirmé Avatar de nmarf
    Inscrit en
    Mai 2003
    Messages
    92
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 92
    Par défaut
    Citation Envoyé par farscape
    tu as regardé l'occupation GDI ? (c'est une colonne a rajouter dans le gestionnaire de taches).
    Est-ce que tu parles de la colonne GDI Objects ? Si c'est le cas, impossible de l'afficher sur la machine où je fais les tests (NT allégé), même si on peut la cocher dans le menu Select Columns. Par contre, sur ma machine de travail (XP), pas de problèmes...

    Citation Envoyé par farscape
    sinon si c'est vraiment du memory leaks lance ton programme en trace debug .
    quand tu fermes l'application tu devrais avoir les traces des alloc non relachés .
    (a condition d'avoir les macros :#define new DEBUG_NEW etc..)
    Je ne sais pas si c'est le mode trace debug mais j'ai déjà lancé l'application en debug, poussé le programme dans ses retranchements (ouverture de plus de dialog possible, lecture d'un grand nombre d'images...) et consulté ce que me dit Visual dans la partie Debug : aucune ligne avec Memory leaks n'apparaît, je pense les avoir assez bien chassés

    En tout cas, merci de te pencher sur mon problème.

  6. #6
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    bien
    si pas de problemes coté objets GDI ,pas de leaks detectés coté debug ,
    c'est etrange..
    alors eventuellement attention a l'eventuel melange de la lib CRT avec les differentes lib que peut utiliser ton programme .
    on a evoqué ce probleme avec r0d il n'y a pas trop longtemps.

  7. #7
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 288
    Billets dans le blog
    2
    Par défaut
    Mmhh, ce n'était pas vraiment la même chose. Dans mon cas, c'était l'inverse, c'est à dire que j'obtenais des memory leaks à cause des différentes CRT alors qu'il n'y en avait pas.

    En ce qui concerne les memory leaks, tu utilise bien la fonction _CrtCheckMemoryLeaks()?

  8. #8
    Membre confirmé Avatar de nmarf
    Inscrit en
    Mai 2003
    Messages
    92
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 92
    Par défaut
    Citation Envoyé par r0d
    En ce qui concerne les memory leaks, tu utilise bien la fonction _CrtCheckMemoryLeaks()?
    Non, je lance juste en mode Debug et je consulte Visual après l'exécution.
    Je n'ai rien trouvé à propos de _CrtCheckMemoryLeaks().
    Sinon, je viens d'essayer _CrtCheckMemory() dans la fonction de fermeture de l'appli et elle ne me renvoie rien de particulier.
    :

  9. #9
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    moi ça m'inspire une chose :
    Ou le constat est erroné ou les méthodes de diagnostics en debug sont shuntées.(macro citée plus haut absente )
    Il faut reprendre depuis le début et établir un constat clair et quantifiable
    Par le gestionnaire de tache et le debugger en mettant des points d'arrêts à des endroits stratégiques.
    Exemple : avant de sortir du programme dans Exitinstance ou dans le destructeur de la classe d’application.
    Que dit le gestionnaire des taches en occupation mémoire du process ?


  10. #10
    Membre confirmé Avatar de nmarf
    Inscrit en
    Mai 2003
    Messages
    92
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 92
    Par défaut
    Bonjour,

    Je n'ai pas trouvé de fonction ExitInstance mais avec le destructeur de ma classe principale (qui n'existait pas, j'ai du le rajouter) et le gestionnaire des tâches, j'ai ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
                                  Mem Usage   GDI Objects
    1ère ligne du constructeur    5064k       29
    fin de l'init de l'appli      6596k       59
    après le chargement d'images  12036k      75
    dans le destructeur           12036k      70

  11. #11
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    il semble bien que tu as des fuites GDI non ?


  12. #12
    Membre confirmé Avatar de nmarf
    Inscrit en
    Mai 2003
    Messages
    92
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 92
    Par défaut
    A quoi vois-tu ça, et quelles peuvent en être les causes ?
    (désolé mais j'ai tant à apprendre...)

  13. #13
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    Citation Envoyé par nmarf
    A quoi vois-tu ça, et quelles peuvent en être les causes ?
    (désolé mais j'ai tant à apprendre...)
    et bien si je ne me trompe pas tu as 59 objets GDI ouvert quand ton application est initialisée en sortie tu as 70 objets..
    apres le chargement d'images tu as 12036 K en memoire .
    dans le destructeur toujours pareil ...
    sauf si le gestionnaire de taches n'a pas pu mettre a jour ses infos c'est pas normal..
    peut etre qu'un afxmessageBox dans le destructeur en release serait plus juste.
    la cause ,objet gdi non relachés, DC sans releaseDC (suivant les cas) ,bitmap ,sans voir le code difficile de repondre .

  14. #14
    Membre confirmé Avatar de nmarf
    Inscrit en
    Mai 2003
    Messages
    92
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 92
    Par défaut
    J'ai trouvé un outil (ICI) qui permet de savoir le type et le nombre de GDI utilisés pour chaque process en cours. Il est même possible de voir le contenu de certains. J'ai relevé les valeurs à chaque étape en Release et voilà ce que ça donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
       Name            ID    #Handles  Bitmap  Brush  DC  Font  Palette  Pen  ExtPen  Region  Other
    1. OfflineBrowser  5184  43 [41]   2       14     2   15    0        1    0       7       0
    2. OfflineBrowser  5184  65 [61]   14      17     4   18    1        1    0       6       0
    3. OfflineBrowser  5184  79 [75]   16      27     5   18    1        2    0       6       0
     
    1. MessageBox à la 1ère ligne du constructeur
    2. Début de l'appli
    3. Lecture de beaucoup d'images
    Les Bitmaps visibles dans l'outil sont les boutons utilisés (classe dérivée des KbcButtons trouvés ICI)

    Par contre, j'ai eu beau mettre un MessageBox dans le destructeur de la classe d'application, il ne s'affiche pas. C'est étonnant car j'arrive à m'y arrêter en Debug avec un point d'arrêt.

  15. #15
    Membre confirmé Avatar de nmarf
    Inscrit en
    Mai 2003
    Messages
    92
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 92
    Par défaut
    En Debug, j'ai les mêmes valeurs. La différence est juste que je peux les récupérer au moment de la destruction, ce qui me donne ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Name            ID    #Handles  Bitmap  Brush  DC  Font  Palette  Pen  ExtPen  Region  Other
    OfflineBrowser  7672  74 [70]   15      25     5   16    1        2    0       6       0

  16. #16
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 35
    Par défaut
    après avoir utilisé un objet GDI, par exemple un CPen ou un CBrush, il faut le détruire avec sa méthode DeleteObject()...

    Je ne sais pas si ça peut t'aider

  17. #17
    Membre confirmé Avatar de nmarf
    Inscrit en
    Mai 2003
    Messages
    92
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 92
    Par défaut
    Est-ce qu'il faut utiliser DeleteObject à chaque fois ? Il me semble avoir lu que les objets étaient détruits proprement dès qu'ils sont hors de portée. Dans quels cas alors n'est-ce pas le cas ?

  18. #18
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    Citation Envoyé par nmarf
    Est-ce qu'il faut utiliser DeleteObject à chaque fois ? Il me semble avoir lu que les objets étaient détruits proprement dès qu'ils sont hors de portée. Dans quels cas alors n'est-ce pas le cas ?
    c'est le cas ,donc a priori si ce n'est pas des pointeurs pas de pb.
    par contre si jamais tu utilises GetDC il faut veiller a faire un ReleaseDC.

  19. #19
    Membre confirmé Avatar de nmarf
    Inscrit en
    Mai 2003
    Messages
    92
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 92
    Par défaut
    Citation Envoyé par farscape
    c'est le cas ,donc a priori si ce n'est pas des pointeurs pas de pb.
    par contre si jamais tu utilises GetDC il faut veiller a faire un ReleaseDC.
    Pas de GetDC dans le code, mais par contre il y a des pointeurs. Par exemple un CBrush* dans ce bout de la fonction OnPaint de la classe d'application :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    		HRSRC hRes; 
    		HGLOBAL hData, hLockedData;
    		CBrush brush;
     
    		hRes = ::FindResource(AfxGetResourceHandle(),  MAKEINTRESOURCE(IDB_XX_FOND), RT_BITMAP);
    		if (hRes != NULL)
    		{
    			if (((hData = ::LoadResource(AfxGetResourceHandle(), hRes)) != NULL) && 
    			((hLockedData = (HGLOBAL)::LockResource(hData)) != NULL))	  {}
    		}
    		brush.CreateDIBPatternBrush(hLockedData,		   DIB_RGB_COLORS);
     
    		// Select the brush into the device context.
    		CBrush* pOldBrush = dc.SelectObject(&brush);
     
    		dc.PatBlt( 0, 0, rect.Width(), rect.Height(), PATCOPY    );
     
    		dc.SelectObject(pOldBrush);
     
    		dcImage.SelectObject(pOldBitmap);
     
    		brush.DeleteObject();
    IDB_XX_FOND est un fichier BMP en ressource dont on se sert pour remplir le fond de chaque fenêtre.
    Est-ce que ce code est critique ?

  20. #20
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 35
    Par défaut
    Citation Envoyé par nmarf
    Est-ce qu'il faut utiliser DeleteObject à chaque fois ? Il me semble avoir lu que les objets étaient détruits proprement dès qu'ils sont hors de portée. Dans quels cas alors n'est-ce pas le cas ?
    Moi il me semble que les objets GDI ne sont pas désalloué sans appel à DeleteObject. De plus, la msdn conseille son utilisation dès qu'un objet GDI n'est plus utilisé.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 8
    Dernier message: 17/09/2007, 20h16
  2. [MFC] Problème de mémoire
    Par benahpets dans le forum MFC
    Réponses: 8
    Dernier message: 03/11/2005, 17h08
  3. Problème de mémoire avec BDE
    Par Machuet dans le forum Bases de données
    Réponses: 3
    Dernier message: 13/07/2004, 10h11
  4. [servlet]problème de variable jamais nulle
    Par omega dans le forum Servlets/JSP
    Réponses: 2
    Dernier message: 18/03/2004, 09h31
  5. [MFC] problème d'éxécution
    Par ben_iap dans le forum MFC
    Réponses: 2
    Dernier message: 15/03/2004, 10h31

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