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

Lazarus Pascal Discussion :

Fuite mémoire incompréhensible à la clôture du programme [Lazarus]


Sujet :

Lazarus Pascal

  1. #1
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 700
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 700
    Points : 15 043
    Points
    15 043
    Par défaut Fuite mémoire incompréhensible à la clôture du programme
    Bonjour,

    Toujours avec mon vieux Laz 1.4/FPC 2.6.2 (la migration est pour bientôt), je suis sur un petit projet d'affichage de la forme d'onde du son d'un fichier audio .wav (44100 Hz, stereo), inspiré de CustLoop de la librairie Bass.
    Tout se passe parfaitement bien sauf à la clôture où la console m'agresse violemment alors que j'ai bien pris soin de faire un free des objets created auparavant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    WARNING: TLCLComponent.Destroy with LCLRefCount>0. Hint: Maybe the component is processing an event?
    [TGtk2WidgetSet.Destroy] WARNING: There are 3 unreleased DCs, a detailed dump follows:
    [TGtk2WidgetSet.Destroy]  DCs:   B651C470 B651C300 B651C190
    [TGtk2WidgetSet.Destroy] WARNING: There are 18 unreleased GDIObjects, a detailed dump follows:
    [TGtk2WidgetSet.Destroy]   GDIOs: B66B7880 B66B7820 B66B77C0 B66B7760 B66B7700 B66B76A0 B66B7640
    [TGtk2WidgetSet.Destroy]   gdiBitmap: 9
    [TGtk2WidgetSet.Destroy]   gdiBrush: 5
    [TGtk2WidgetSet.Destroy]   gdiPen: 4
    Bien sûr, avec des messages aussi cabalistiques pas moyen d'en savoir plus, et je répète bien que j'ai mis
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
    begin
      BufferG.Free;
      BufferL.Free;
      BufferR.Free;
    end;
    tout comme dans la procédure de chargement du fichier
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
        //creating music stream
        chan1 := BASS_StreamCreateFile(FALSE,pchar(filename),0,0,0 {$IFDEF UNICODE} or BASS_UNICODE {$ENDIF});
        ...
        //getting peak levels
        chan2 := BASS_StreamCreateFile(FALSE,pchar(filename),0,0,BASS_STREAM_DECODE {$IFDEF UNICODE} or BASS_UNICODE {$ENDIF});
        ...
        // affichage, puis
        BASS_StreamFree(chan1);
        BASS_StreamFree(chan2);
    Ce sont les seuls objets que je crée, alors que se passe-t-il avec ce message d'erreur hermétique ?

    PS : en remplaçant le TPaintBox par un TImage, le message d'erreur évolue un peu, sans pour autant gagner en clarté hein, faut pas rêver :
    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
    WARNING: TLCLComponent.Destroy with LCLRefCount>0. Hint: Maybe the component is processing an event?
    [TGtk2WidgetSet.Destroy] WARNING: There are 2 unreleased DCs, a detailed dump follows:
    [TGtk2WidgetSet.Destroy]  DCs:   B635C3E0 B635C220
    [TGtk2WidgetSet.Destroy] WARNING: There are 16 unreleased GDIObjects, a detailed dump follows:
    [TGtk2WidgetSet.Destroy]   GDIOs: B7727D10 B7727C60 B7727B00 B7727A50 B77278F0 B7727840 B7727790
    [TGtk2WidgetSet.Destroy]   gdiBitmap: 8
    [TGtk2WidgetSet.Destroy]   gdiBrush: 4
    [TGtk2WidgetSet.Destroy]   gdiPen: 4
    Heap dump by heaptrc unit
    1021 memory blocks allocated : 1865593/1868032
    970 memory blocks freed     : 1860789/1863096
    51 unfreed memory blocks : 4804
    True heap size : 3473408
    True free heap : 3464416
    Should be : 3465208
    Et si je regarde par exemple cet extrait du log (en utilisant heaptrc) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Call trace for block $B66FD820 size 16
      $080721A8
      $081B43FB
      $08120E05  TCANVAS__CREATE,  line 1492 of ./include/canvas.inc
      $081182DF  TBITMAPCANVAS__CREATE,  line 23 of ./include/bitmapcanvas.inc
      $08115A05  TRASTERIMAGE__CREATECANVAS,  line 308 of ./include/rasterimage.inc
      $081159CB  TRASTERIMAGE__GETCANVAS,  line 300 of ./include/rasterimage.inc
      $08097B4E  TFORM1__DRAWSPECTRUM,  line 239 of Unit1.pas
      $080978CB  TFORM1__LOADFILE,  line 152 of Unit1.pas
    on voit qu'il n'y a que deux endroits où je peux intervenir, les deux dernières lignes.
    La toute dernière se contente d'appeler la procédure de dessin DRAWSPECTRUM qu'on voit en avant-dernière ligne, et sa ligne 239 contient BufferL.Canvas.Brush.Style := bsSolid; et c'est tout.
    C'est ça qui me cause une fuite mémoire ?
    Il y en a sans doute d'autres, en rapport avec BufferR et BufferG (G comme général, il contiendra L et R) mais le log est assez indigeste.

    Faut m'expliquer, là, parce que je rappelle que je free mes buffers dans le FormClose

    Merci pour les pistes et les idées, et bon week-end,
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  2. #2
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 671
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 671
    Points : 13 065
    Points
    13 065
    Par défaut
    L'erreur parle de device context, ton problème est graphique et dû à un GetDC qui ne se termine pas par un ReleaseDC.

    Si on fait un grand bon en arrière (code sous Yakà demander, update the display), on constate que tu fais un DC := GetDC(WndGlobal) mais un ReleaseDC(Window, DC). Ce n'est pas la même fenêtre, ReleaseDC échoue certainement.

    Le problème est peut-être ailleurs mais similaire ; GetDC sans ReleaseDC

  3. #3
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 700
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 700
    Points : 15 043
    Points
    15 043
    Par défaut
    Citation Envoyé par Andnotor Voir le message
    Le problème est peut-être ailleurs mais similaire ; GetDC sans ReleaseDC
    Oui oui oui, sauf que je ne fais pas de GetDC ou similaire, je me contente de faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    procedure TForm1.FormCreate(Sender: TObject);
      BufferG := TBitmap.Create; 
      BufferG.PixelFormat := pf24bit;
      BufferL := TBitmap.Create;
      BufferL.PixelFormat := pf24bit;
      BufferR := TBitmap.Create;
      BufferR.PixelFormat := pf24bit;
      ...
    et de voir écrit ce qui précède comme ça me donne une idée : je fais un test en n'allant pas plus loin :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
      ...
      BufferR.PixelFormat := pf24bit;
    exit;
    end;
    et j'exécute : il ne se passe rien à part l'affichage de la fiche, vide, normal.
    Je la ferme avec ESC (
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    begin
      if key = 27 then Halt; //Application.Terminate;
    end;
    ) et je me prends la même erreur !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    WARNING: TLCLComponent.Destroy with LCLRefCount>0. Hint: Maybe the component is processing an event?
    [TGtk2WidgetSet.Destroy] WARNING: There are 2 unreleased DCs, a detailed dump follows:
    [TGtk2WidgetSet.Destroy]  DCs:   B65A6470 B65A6300
    [TGtk2WidgetSet.Destroy] WARNING: There are 16 unreleased GDIObjects, a detailed dump follows:
    [TGtk2WidgetSet.Destroy]   GDIOs: B6741A60 B6741A00 B67419A0 B6741940 B67418E0 B6741880 B6741820
    [TGtk2WidgetSet.Destroy]   gdiBitmap: 8
    [TGtk2WidgetSet.Destroy]   gdiBrush: 4
    [TGtk2WidgetSet.Destroy]   gdiPen: 4
    Mais en regardant mieux ce que précède (non, pas ces 8 lignes, ce qu'il y a juste avant), je me dis que j'ai peut-être été un peu violent, et après un test tout autant négatif avec if key = 27 then Application.Terminate;, la solution est toute simple : if key = 27 then Close; puisque les "Free" sont dans FormClose.

    (je pensais naïvement que Halt ou Application.Terminate auraient fait passer par FormClose mais non.)

    Allez hop !, terminé, et merci de m'avoir mis sur la piste.
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  4. #4
    Membre éprouvé Avatar de der§en
    Homme Profil pro
    Chambord
    Inscrit en
    Septembre 2005
    Messages
    754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Chambord
    Secteur : Transports

    Informations forums :
    Inscription : Septembre 2005
    Messages : 754
    Points : 943
    Points
    943
    Par défaut
    Perso, j’ai tendance à privilégier le OnDestroy…

  5. #5
    Expert éminent
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 663
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 663
    Points : 6 949
    Points
    6 949
    Par défaut
    Citation Envoyé par Jipété Voir le message
    (je pensais naïvement que Halt ou Application.Terminate auraient fait passer par FormClose mais non.)
    C'est des demandes d'arrêt de l'application plutôt brutales.
    Ca doit être pour ça ...
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. ___ Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.3.2 Entreprise - Delphi 10.4.2 Entreprise
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (11.6 - 14.6)

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

Discussions similaires

  1. [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, 11h41
  2. [Fuites mémoire] Je cherche un utilitaire
    Par 10_GOTO_10 dans le forum C++Builder
    Réponses: 8
    Dernier message: 10/02/2005, 11h03
  3. Outil de recherche de fuite mémoire
    Par eag35 dans le forum MFC
    Réponses: 4
    Dernier message: 02/02/2005, 13h46
  4. [SWT]SWT et fuite mémoire(ou pas)
    Par menuge dans le forum SWT/JFace
    Réponses: 2
    Dernier message: 22/06/2004, 22h40
  5. [debug] fuites mémoires
    Par tmonjalo dans le forum C
    Réponses: 3
    Dernier message: 28/07/2003, 18h20

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