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

Langage Delphi Discussion :

Eviter une fuite mémoire sur un thread


Sujet :

Langage Delphi

  1. #1
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut Eviter une fuite mémoire sur un thread
    Bonjour à tous et à toutes ,

    Je voudrais savoir comment éviter une fuite mémoire lorsqu'on stop un thread.



    Evidement, j'ai activé ReportMemoryLeaksOnShutDown := true; dans mon dpr

    Cela arrive si je stop mon téléchargement encours en fermant mon application


    J'ai essayé de jouer avec le destructor du thread, mais je ne sais pas quoi libérer, voici un des threads concerné :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Destructor TDownloadStatus.Destroy;
    begin
      FreeAndNil('????');
      inherited;
    end;
    Le Thread
    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
      TDownloadStatus = class(TInterfacedObject, IBindStatusCallback)
      private
        Wnd :hWnd;
      public
        function OnStartBinding(dwReserved: DWORD; pib: IBinding): HResult; stdcall;
        function GetPriority(out nPriority): HResult; stdcall;
        function OnLowResource(reserved: DWORD): HResult; stdcall;
        function OnProgress(ulProgress, ulProgressMax, ulStatusCode: ULONG; szStatusText: LPCWSTR): HResult; stdcall;
        function OnStopBinding(hresult: HResult; szError: LPCWSTR): HResult; stdcall;
        function GetBindInfo(out grfBINDF: DWORD; var bindinfo: TBindInfo): HResult; stdcall;
        function OnDataAvailable(grfBSCF: DWORD; dwSize: DWORD; formatetc: PFormatEtc; stgmed: PStgMedium): HResult; stdcall;
        function OnObjectAvailable(const iid: TGUID; punk: IUnknown): HResult; stdcall;
      public
        Constructor Create(const aWnd :hWnd);
        Destructor Destroy; override; { Destructeur }
      end;

    Et pour le deuxieme, cela ne change rien :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Destructor TDownloadNewVersionThread.Destroy;
    begin
      FreeAndNil(Status);
      inherited;
    end;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
      //Tâche téléchargement
      TDownloadNewVersionThread = class(TThread)
      private
        Wnd        :hWnd;        //Fenêtre qui reçoit les notifications
        RemoteFile :string;      //HTTP://... fichier nouvelle version
        Status     :TDownloadStatus;
      protected
        procedure Execute; override;
      public
        constructor Create(const aWnd :hWnd; const aRemoteFile :string);
        Destructor Destroy; override; { Destructeur }
      end;

    Merci.

  2. #2
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 862
    Points : 11 321
    Points
    11 321
    Billets dans le blog
    6
    Par défaut
    pour terminer les threads, ne faut-il pas leur setter Terminated à True et tester Terminated dans leur boucle du Execute ?
    à condition que FreeOnTerminate, ils se libèreront, non ?
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    707
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 707
    Points : 777
    Points
    777
    Par défaut
    Comment stoppes-tu ton thread quand il y a demande de fermeture de la fiche ?

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 743
    Points : 13 299
    Points
    13 299
    Par défaut
    Si ces erreurs étaient systématiques et augmentaient avec le temps, je me poserais certainement des questions (mais surtout en runtime)
    Sinon, en sachant que la mémoire du processus est entièrement libérée à sa terminaison, inutile de se soucier d'une chaîne non désallouée. (elle le sera de toute façon)

  5. #5
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut
    Citation Envoyé par tourlourou;
    pour terminer les threads, ne faut-il pas leur setter Terminated à True et tester Terminated dans leur boucle du Execute ?
    Je ne peux pas faire de teste sur terminated à true.

    Citation Envoyé par GoustiFruit;
    Comment stoppes-tu ton thread quand il y a demande de fermeture de la fiche ?
    Dans chaque create des Threads avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      //Libération automatique à la fin du thread
      FreeOnTerminate := TRUE;
    Citation Envoyé par Andnotor Voir le message
    Si ces erreurs étaient systématiques et augmentaient avec le temps, je me poserais certainement des questions (mais surtout en runtime)
    Sinon, en sachant que la mémoire du processus est entièrement libérée à sa terminaison, inutile de se soucier d'une chaîne non désallouée. (elle le sera de toute façon)
    Salut Andnotor,

    Tu as tout à fait raison, une fois l'application fermée tout est désalouée.
    Je voulais apprendre, savoir si c'était possible.
    après beaucoup de test différent je n'ai pas trouvé le moyen de le faire, je suis même arrivé à faire pire... lol

  6. #6
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut
    Bjr,

    J'ai du louper un Wagon, il n'y a plus de bouton DELESTAGE ?

    (Ps: dans les options non plus)

    Merci.

  7. #7
    Membre chevronné

    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2009
    Messages
    935
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2009
    Messages : 935
    Points : 1 765
    Points
    1 765
    Par défaut
    Citation Envoyé par BuzzLeclaire Voir le message
    Bjr,

    J'ai du louper un Wagon, il n'y a plus de bouton DELESTAGE ?

    (Ps: dans les options non plus)

    Merci.
    Salut

    En effet, c'est depuis un moment : http://www.developpez.net/forums/d11...olu-delestage/

  8. #8
    Expert confirmé

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Leader Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Points : 4 173
    Points
    4 173
    Par défaut
    Citation Envoyé par tourlourou Voir le message
    pour terminer les threads, ne faut-il pas leur setter Terminated à True et tester Terminated dans leur boucle du Execute ?
    à condition que FreeOnTerminate, ils se libèreront, non ?
    En fait le FreeOnTerminate ne fonctionne que lorsque la méthode Execute du thread rend la main :
    Lorsque la classe TThread est instanciée, en interne celà provoque l'appel à CreateThread sur une procédure qui appelle à son tour la méthode Execute du thread. Lorsque Execute rend la main, la procédure interne utilisée pour appeler Execute teste si FreeOnTerminate est activé et détruit l'instance de TThread avant de rendre la main et que le thread Windows ne se termine.

    Autrement dit, ça fonctionne si Execute rend la main parce que le traitement est finit ou que dans le traitement du thread, on teste Terminated pour quitter Execute.
    Cependant, si c'est le thread windows qui est tué (un arrêt brutal du thread, par exemple avec TerminateThread), c'est l'exécution de la procédure interne qui a appelé Execute qui est stoppée. FreeOnterminate ne sera pas testé et l'instance du thread restera...

    Dans le cas de BuzzLeclaire, à la fermeture de la fenêtre, il faudrait contrôler s'il existe encore des TDownloadNewVersionThread en cours d'exécution. Si c'est le cas, il faut notifier au thread qu'il doit s'arrêter, et s'il est en attente d'un objet de synchronisation, il faut débloquer le thread pour qu'il s'arrête proprement.

    Sinon, en sachant que la mémoire du processus est entièrement libérée à sa terminaison, inutile de se soucier d'une chaîne non désallouée. (elle le sera de toute façon)
    Le problème c'est que s'il reste des threads en cours d'exécution, le process reste aussi en mémoire et ne se termine pas. Apparemment ici les threads ont l'air d'avoir été tués violament donc ça ne poserait pas de problème, mais il serait plus sûr de faire le ménage correctement.

  9. #9
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 862
    Points : 11 321
    Points
    11 321
    Billets dans le blog
    6
    Par défaut
    @Franck : tu as parfaitement explicité ce que j'avais "résumé" ! Et en y ajoutant le problème de Synchro, auquel je n'avais pas pensé... Tu as également raison de souligner que ce n'est possible que si la méthode Execute se prête à l'écoute du Terminated.
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 743
    Points : 13 299
    Points
    13 299
    Par défaut
    Ce que je voulais dire est que ReportMemoryLeaksOnShutDown nous renvoi un état des lieux à la fin du thread principal.
    Si pour une raison quelconque le thread secondaire prend plus de temps à s'arrêter que le principal (il n'est pas forcément en attente), un memory leak sera reporté. Ce qui ne veux pas dire que la mémoire ne sera pas libérée normalement par la suite...

    Si le problème est sporadique, ce n'est pas forcément une erreur. Juste un faux signal négatif. S'il est systématique, oui je me ferais du soucis
    Si le processus ne se termine pas, la question ne se pose pas... Y'a du boulot !

    Enfin je peux me tromper...

Discussions similaires

  1. Fuite mémoire sur une classe template.
    Par robinsondesbois dans le forum Langage
    Réponses: 17
    Dernier message: 11/07/2013, 16h38
  2. Fuite mémoire sur composants Indy 9.0.50
    Par Fbartolo dans le forum C++Builder
    Réponses: 15
    Dernier message: 30/04/2009, 15h47
  3. Localiser une fuite mémoire en C++
    Par echecetmat dans le forum Débuter
    Réponses: 2
    Dernier message: 12/11/2008, 16h42
  4. [ATL-COM] Identifier l'origine d'une fuite mémoire
    Par Mat.M dans le forum Visual C++
    Réponses: 5
    Dernier message: 20/06/2007, 19h47
  5. Problème de fuite mémoire sur un idFTP
    Par jeromelef dans le forum Composants VCL
    Réponses: 6
    Dernier message: 26/07/2005, 17h29

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