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 :

Problème pour détruire une Form


Sujet :

Langage Delphi

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 107
    Points : 41
    Points
    41
    Par défaut Problème pour détruire une Form
    bonjour,

    dans mon application je définis des form de la manière suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    chat_form                         : Array [0..nb_form] Of Tchat_unit;
    ensuite, pour libérer un peu de mémoire (car en tout il y a plusieurs dizaines de forms ), et bien je fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if chat_form[ID]<>nil then begin
            chat_form[ID].Free;
            chat_form[ID]:=nil;
          end;
    mais à ce moment là j'ai un message m'indiquant : "invalid pointer operation" :S

    sauriez-vous comment faire pour libérer le plus de mémoire possible ?

    merci

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

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 879
    Points : 15 311
    Points
    15 311
    Par défaut
    Citation Envoyé par Shredder Voir le message
    sauriez-vous comment faire pour libérer le plus de mémoire possible ?
    Probablement avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if chat_form[ID]<>nil then begin
            chat_form[ID].Free;
            // chat_form[ID]:=nil; // libéré au-dessus donc inutile
          end;
    Mes 2 cts,
    --
    jp

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 107
    Points : 41
    Points
    41
    Par défaut
    le problème quand je fais ceci, c'est que ensuite la mémoire utilisée par mon application augmente considérablement, et ne baisse que très peu quand je supprime toutes les formes

    est-ce que ce code libère aussi tous les composants de chaque forme ?

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

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 879
    Points : 15 311
    Points
    15 311
    Par défaut
    Citation Envoyé par Shredder Voir le message
    le problème quand je fais ceci, c'est que ensuite la mémoire utilisée par mon application augmente considérablement, et ne baisse que très peu quand je supprime toutes les formes
    Si je relis bien ce que tu as écrit, c'est le ensuite qui m'ennuie...
    Y a quelque chose de pas clair, là, puisque le code est sensé supprimer les forms..

    Citation Envoyé par Shredder Voir le message
    lest-ce que ce code libère aussi tous les composants de chaque forme ?
    Normalement oui, enfin, si les composants (créés dynamiquement je suppose) ont bien la form comme parent.
    --
    jp

  5. #5
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 875
    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 875
    Points : 11 365
    Points
    11 365
    Billets dans le blog
    6
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    FreeAndNil(chat_form[ID]); //devrait suffire
    mais plutôt que de mettre les TChatForm dans un tableau de dimension fixe, tu devrais pê les mettre dans une liste (et les en enlever en les libérant)

  6. #6
    Membre émérite Avatar de edam
    Homme Profil pro
    Développeur Delphi/c++/Omnis
    Inscrit en
    Décembre 2003
    Messages
    1 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Delphi/c++/Omnis
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 894
    Points : 2 770
    Points
    2 770
    Par défaut
    Citation Envoyé par Shredder Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if chat_form[ID]<>nil then begin
            chat_form[ID].Free;
            chat_form[ID]:=nil; //est juste c'est pour le test aprés :if chat_form[ID]<>nil 
          end;
    mais je crois que tu dois remplacé free par release
    dans l'aide de delphi:
    TCustomForm.Release

    procedure Release;
    Description
    Utilisez la méthode Release pour détruire la fiche et libérer la mémoire associée.
    Release ne détruit pas la fiche avant que tous les gestionnaires d'événements de la fiche et des composants de la fiche n'aient eu le temps de terminer leur exécution. Tous les gestionnaires d'événement de la fiche doivent utiliser Release à la place de Free. Si vous ne respectez pas cette règle, une violation d'accès risque d'être générée.
    Remarque*: Release retourne immédiatement à l'appelant. Elle n'attend pas que la fiche soit libérée.

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 107
    Points : 41
    Points
    41
    Par défaut
    Citation Envoyé par Jipété Voir le message
    Si je relis bien ce que tu as écrit, c'est le ensuite qui m'ennuie...
    Y a quelque chose de pas clair, là, puisque le code est sensé supprimer les forms..


    Normalement oui, enfin, si les composants (créés dynamiquement je suppose) ont bien la form comme parent.
    --
    jp
    oui non désolé je me suis mal exprimé ^^

    en fait on en est au stade où la mémoire a augmenté et ou je veux tout libérer.

    alors je fais le code .Free (FreeAndNil correspond parfaitement à ce que je cherchais )

    mais la taille de l'application reste élevée.

    Release semble alors plus approprié en effet, et qu'en est-il de FreeOnRelease ?

  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
    mais à ce moment là j'ai un message m'indiquant : "invalid pointer operation" :S
    Si tu as ce message, c'est que tu essaies de libérer un objet qui a déjà été détruit !
    Est-ce que tes forms n'auraient pas un Action := caFree sur l'événement OnClose ?
    Si c'est le cas, les fiches en question sont détruites dès leur fermeture...

    lest-ce que ce code libère aussi tous les composants de chaque forme ?
    Normalement oui, enfin, si les composants (créés dynamiquement je suppose) ont bien la form comme parent.
    Plus exactement, si les composants ont la form comme Owner. Le parent ne sert que pour Windows.

    Ensuite Release plutôt que free changera uniquement le moment où la fiche sera détruite. Ca ne changera rien à ton problème mémoire.

    Plusieurs remarques concernant la mémoire :
    - Je ne pense pas qu'une dizaine de fiches avec leurs composants, même complêxes puissent avoir une occupation mémoire aussi significative que tu sembles l'indiquer. Tu dois plutôt avoir un memory leak sur une autre structure de données (peut-être un datamodule lié qui ne serait pas libéré...).
    - Comment fais-tu pour contrôler la mémoire utilisée ? Si tu te contentes de regarder la mémoire utilisée par le processus dans le gestionnaire des tâches Windows, ça peut être très trompeur. D'abord, par défaut ce dernier n'affiche que la mémoire physique utilisée et pas la mémoire virtuelle (réduit ton application, tu verras la mémoire utilisée dans le gestionnaire des tâches diminuer d'un coup). Ensuite, Delphi possède son propre gestionnaire de mémoire par dessus Windows. Ce dernier demande de la mémoire par gros bloc à l'OS, et ne la rend également que par blocs entiers. Lorsque tu détruis une fiche, tu rends la mémoire disponible pour ton application, mais ça ne veut pas nécessairement dire que Delphi va rendre la mémoire à l'OS, surtout si cette dernière est fragmentée...

    Cependant, si la consommation mémoire est si significative que ça, c'est que tu dois avoir un memory leak, ou que la mémoire n'est pas utilisée par les objets que tu penses...

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

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 879
    Points : 15 311
    Points
    15 311
    Par défaut
    Citation Envoyé par Franck SORIANO Voir le message
    (réduit ton application, tu verras la mémoire utilisée dans le gestionnaire des tâches diminuer d'un coup).
    Je regarde mon Gestionnaire de tâches (w2k) en même temps que j'écris ça, je réduis Firefox et ne note aucune différence significative (c'est plutôt en le "remontant" qu'il en consomme !). Ta remarque ne s'appliquerait-elle pas au cas où il n'y a plus de mémoire physique (RAM) libre ?

    + 1 pour le Memory Leak.

    Merci pour la correction Parent/Owner.
    --
    jp

  10. #10
    Rédacteur
    Avatar de evarisnea
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Juin 2005
    Messages
    1 957
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : Transports

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 957
    Points : 4 384
    Points
    4 384
    Par défaut
    Citation Envoyé par Jipété Voir le message
    Je regarde mon Gestionnaire de tâches (w2k) en même temps que j'écris ça, je réduis Firefox et ne note aucune différence significative (c'est plutôt en le "remontant" qu'il en consomme !). Ta remarque ne s'appliquerait-elle pas au cas où il n'y a plus de mémoire physique (RAM) libre ?
    la remarque de franck est bien justifiée, c'est firefox qui n'en fait qu'à sa tête et consomme trop de mémoire. essaie la manipulation avec le bloc notes par exemple, ou un projet d'une form et tu verras

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

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 879
    Points : 15 311
    Points
    15 311
    Par défaut
    Citation Envoyé par evarisnea Voir le message

    la remarque de franck est bien justifiée, c'est firefox qui n'en fait qu'à sa tête et consomme trop de mémoire. essaie la manipulation avec le bloc notes par exemple, ou un projet d'une form et tu verras
    Bien vu !
    Comme quoi, hein, on n'est pas au bout de nos surprises : je lance le bloc-notes il occupe 1632 ko, je le réduis il tombe à 132 ko, je le remonte il est à 356 ko.
    Va comprendre...
    Bon dimanche,
    --
    jp

  12. #12
    Membre émérite Avatar de edam
    Homme Profil pro
    Développeur Delphi/c++/Omnis
    Inscrit en
    Décembre 2003
    Messages
    1 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Delphi/c++/Omnis
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 894
    Points : 2 770
    Points
    2 770
    Par défaut
    Citation Envoyé par Franck SORIANO Voir le message
    Si tu as ce message, c'est que tu essaies de libérer un objet qui a déjà été détruit !
    +1
    Citation Envoyé par Franck SORIANO Voir le message
    Ensuite Release plutôt que free changera uniquement le moment où la fiche sera détruite. Ca ne changera rien à ton problème mémoire.
    Pas d'accord avec toi,
    Release ne détruit pas la fiche avant que tous les gestionnaires d'événements de la fiche et des composants de la fiche n'aient eu le temps de terminer leur exécution. Tous les gestionnaires d'événement de la fiche doivent utiliser Release à la place de Free. Si vous ne respectez pas cette règle, une violation d'accès risque d'être générée.
    en plus selon le 1er poste:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    chat_form : Array [0..nb_form] Of Tchat_unit;
    sa veux dire qu'il utlise les sockets, alors au moins il faut arréter la connection socket, avant de détruire la forme, car à la fermeture(la déstruction de winsock) il envoit un evenemnt de fermeture, et si en utlise free, l'evenement ne sera pas trouver,

  13. #13
    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
    Pas d'accord avec toi,
    Release ne détruit pas la fiche avant que tous les gestionnaires d'événements de la fiche et des composants de la fiche n'aient eu le temps de terminer leur exécution. Tous les gestionnaires d'événement de la fiche doivent utiliser Release à la place de Free. Si vous ne respectez pas cette règle, une violation d'accès risque d'être générée.
    en plus selon le 1er poste:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    chat_form : Array [0..nb_form] Of Tchat_unit;
    sa veux dire qu'il utlise les sockets, alors au moins il faut arréter la connection socket, avant de détruire la forme, car à la fermeture(la déstruction de winsock) il envoit un evenemnt de fermeture, et si en utlise free, l'evenement ne sera pas trouver,
    Possible mais je ne suis pas convaincu. A moins que le code ne soit vraiment très tordu, il est peu probable qu'une destruction prématurée de la fiche est pour effet d'essayer de la détruire deux fois...

  14. #14
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 107
    Points : 41
    Points
    41
    Par défaut
    merci pour toutes vos réponses

    j'ai finalement mis des releases sur toutes les form (vu qu'il n'y avait pas que des chat_unit) et finalement la mémoire augmente donc pas mal la premiere fois, du genre l'application passe de 16 000 a 25 000 ko. Suite a la suppression des forms -> je passe a 22 000 dans le gestionnaire des taches, mais en en recréant / re-supprimant toutes les formes, la mémoire n'augmente que très peu (du genre 200ko a chaque fois mais c'est normal je pense)

    enfin ça marche et ça m'a l'air pas trop mal lol

    merci encore

    (sinon edam il y a effectivement des sockets, et j'ai bien fermé la connexion cette fois )

Discussions similaires

  1. Réponses: 26
    Dernier message: 29/05/2008, 15h13
  2. Réponses: 3
    Dernier message: 03/03/2008, 15h29
  3. Réponses: 13
    Dernier message: 23/12/2004, 18h01
  4. Réponses: 3
    Dernier message: 29/08/2003, 10h57

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