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 de désallocation de mémoire


Sujet :

Langage Delphi

  1. #1
    Nouveau Candidat au Club
    Femme Profil pro
    Développeur
    Inscrit en
    Novembre 2011
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Madagascar

    Informations professionnelles :
    Activité : Développeur
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Novembre 2011
    Messages : 2
    Points : 1
    Points
    1
    Par défaut Problème de désallocation de mémoire
    Bjr à tous,

    Je sais que c'est basique mais j'aimerai savoir comment désallouer la mémoire utilisée par une composante.

    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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
     
    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, DB, ADODB, ExtCtrls;
     
    type
      TForm1 = class(TForm)
        Button1: TButton;
        Button2: TButton;
        Button3: TButton;
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
        procedure Button3Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
     
    var
      Form1: TForm1;
      AdoConn : TADOConnection;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm1.Button1Click(Sender: TObject);
    begin
            AdoConn := TADOConnection.Create(nil);
    end;
     
    procedure TForm1.Button2Click(Sender: TObject);
    begin
            AdoConn.Free;
    end;
     
    procedure TForm1.Button3Click(Sender: TObject);
    var
            i : integer;
    begin
            for i := 1 to 1000 do
            begin
                    Button1Click(Sender);
                    Button2Click(Sender);
            end;
            ShowMessage('Terminé');
    end;
     
    end.
    1. Sur ma Form, j'ai 3 boutons. J'ai également déclarée une variable AdoConn : TADOConnection;. Au lancement de ma petite application, en vérifiant dans le gestionnaire de tâche :
    ==> Mémoire utilisée = 3 320 Ko

    2. Je clique sur un bouton qui crée dynamiquement une ADOConnection, comme suit :
    AdoConn := TADOConnection.Create(nil);
    ==> Mémoire utilisée = 4 520 Ko

    3. Je clique sur un autre bouton dans lequel je libère mon ADOConnection :
    AdoConn.Free;
    ==> Mémoire utilisée = 4 526 Ko (là je ne comprend pas ? au lieu de me libérer de la mémoire, ça m'en rajoute ???)

    4. En répétant plusieurs fois l'opération, ma mémoire augmente de plus en plus.

    Quelqu'un pourrait-il m'aider à comprendre et me dire comment faire pour désallouer correctement un TADOConnection créée dynamiquement.

    Merci à tous

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 664
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 664
    Points : 25 458
    Points
    25 458
    Par défaut
    Lit donc ce sujet sur la fragmentation et la gestion par bloc de la mémoire : RAM non utilisée
    en particulier les interventions de Paul TOTH et de Franck SORIANO
    Cela peut te donner une explication sur la faible récupération de mémoire malgré un Free !

    Même, si ton problème est effectivement assez étrange, on pourrait comprendre que l'on ne récupère que partiellement mais pas que cela augmente !


    Pense que tu peux mettre le TADOConnection dans un TDataModule ou directement sur la Form, il sera automatiquement libéré

    As-tu une différence si AdoConn est un membre privé de TForm1 ?
    As-tu une différence si tu fournis Self comme Owner lors du Create ?
    As-tu une différence si tu affecte nil après le Free ?
    Comme il y a derrière l'objet des interfaces, il y a peut-être une fuite à ce sujet
    Si tu joue avec Active, as-tu une consommation\réduction plus importante ?

    Le TXMLDocument a une gestion différente des interfaces et de leur compteur de référence en fonction si on le créer avec ou sans Onwer, le TADOConnection a peut-être un comportement similaire ?

    En général, on peut utiliser un Singleton pour le TADOConnection
    Un seul objet est suffisant pour l'ensemble de programme (cela supporte même l'utilisation entre thread, même si en général, je préfère faire un Multiton et une Factory\Registry qui gère un objet différent par Thread)

  3. #3
    Nouveau Candidat au Club
    Femme Profil pro
    Développeur
    Inscrit en
    Novembre 2011
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Madagascar

    Informations professionnelles :
    Activité : Développeur
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Novembre 2011
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    Bonjour,

    As-tu une différence si AdoConn est un membre privé de TForm1 ?
    As-tu une différence si tu fournis Self comme Owner lors du Create ?
    As-tu une différence si tu affecte nil après le Free ?
    Non, je l'avais initialement mis comme membre privé de la form et le même phénomène se produit à savoir augmentation de l'utilisation mémoire au moment du Free de l'ordre de +/-10 Ko environ à chaque fois.

    Si tu joue avec Active, as-tu une consommation\réduction plus importante ?
    Oui, effectivement. Quand j'essaye de me connecter à une base (SQL Server pour info) ça passe de 4 526 Ko à 7 500 Ko environ. Et en refermant la connexion, il y toujours les +/-10Ko d'augmentation.

    En général, on peut utiliser un Singleton pour le TADOConnection
    Un seul objet est suffisant pour l'ensemble de programme (cela supporte même l'utilisation entre thread, même si en général, je préfère faire un Multiton et une Factory\Registry qui gère un objet différent par Thread)
    Pense que tu peux mettre le TADOConnection dans un TDataModule ou directement sur la Form, il sera automatiquement libéré
    Je vais explorer ces pistes pour voir ce que ça donne. C'est vrai que je n'ai pas trop l'habitude d'utiliser le TDataModule !

    En tout cas, merci pour tes conseils, notamment pour le sujet de référence qui est très instructif.

  4. #4
    Membre chevronné Avatar de philnext
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    1 552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 1 552
    Points : 1 780
    Points
    1 780
    Par défaut
    Juste pour être sûr, tu n'as pas de pb de libération, tu as testé avec FastMM4 ou autre ?

  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
    Salut,

    Moi je ferais plutot cela

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    procedure TForm1.Button2Click(Sender: TObject);
    begin
       AdoConn.connected := False;
       if Assigned(AdoConn) Then FreeAndNil(AdoConn);
    end;

    Regarde si cela change.

  6. #6
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 457
    Points
    28 457
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    As-tu une différence si AdoConn est un membre privé de TForm1 ?
    As-tu une différence si tu fournis Self comme Owner lors du Create ?
    As-tu une différence si tu affecte nil après le Free ?
    - privé on non ça ne change rien
    - le owner n'a pas d'importance dans la mesure ou le composant est explicitement supprimé par Bouton2
    - l'affectation de nil à la variable n'a pas d'incidence sur l'occupation mémoire

    je viens de faire le teste sous D6

    au lancement : 896K (dans le gestionnaire de tâche)
    Bouton1.Click : 1180K
    Bouton2.Click : ça ne change pas
    Bouton1.Click : ça ne bouge pas

    avec ce code je passe à 1188K
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    procedure TForm1.Button3Click(Sender: TObject);
    var
      i : Integer;
      a : TADOConnection;
    begin
      for i := 1 to 1000 do
      begin
        a := TADOConnection.Create(nil);
        a.Free;
      end;
    end;
    le même code sous XE2 donne fait passer la mémoire de 1500K à 2000K contre 1980K sur une seule instance

    et avec un ReportMemoryLeaksOnShutdown := True; je n'ai pas de fuite mémoire.

    la mémoire n'est pas rendu à Windows mais elle est disponible pour l'application (heap), et il y a une petite fragmentation sur la boucle mais rien d'extraordinaire.

  7. #7
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 664
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 664
    Points : 25 458
    Points
    25 458
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    As-tu une différence si AdoConn est un membre privé de TForm1 ?
    As-tu une différence si tu fournis Self comme Owner lors du Create ?
    As-tu une différence si tu affecte nil après le Free ?
    Citation Envoyé par Paul TOTH Voir le message
    - privé on non ça ne change rien
    - le owner n'a pas d'importance dans la mesure ou le composant est explicitement supprimé par Bouton2
    - l'affectation de nil à la variable n'a pas d'incidence sur l'occupation mémoire
    Je voulais m'assurer que le code fourni correspondait bien aux tests effectués ! Qu'ils ne trainaient pas d'autres variables qui pourraient fausser les tests !
    On ne sait jamais !

    Pour le Owner vu le comportement étrange du TXMLDocument avec ses interfaces internes et vu que le TADOConnection utilise des interfaces aussi, je préfère poser la question, comme on dit entre la théorie et la pratique ...



    Sinon, selon tes autres remarques, il y a donc DEUX comportements différents !
    Quel l'OS chez chacun de vous deux ?

  8. #8
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 457
    Points
    28 457
    Par défaut
    win7/64

Discussions similaires

  1. Réponses: 2
    Dernier message: 17/06/2010, 08h32
  2. allocation/désallocation de mémoire
    Par kinta dans le forum C++
    Réponses: 2
    Dernier message: 10/02/2006, 09h52
  3. Problème d'allocation de mémoire dans la pile
    Par prophet666 dans le forum x86 32-bits / 64-bits
    Réponses: 6
    Dernier message: 19/01/2006, 02h22
  4. Désallocation de mémoire ...
    Par Mike888 dans le forum C
    Réponses: 9
    Dernier message: 18/01/2006, 10h42
  5. [Debutant(e)]problème de libération de mémoire
    Par skywalker3 dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 10/02/2005, 17h38

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