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

Composants VCL Delphi Discussion :

Utilisation Mémoire d'une application


Sujet :

Composants VCL Delphi

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 25
    Points : 20
    Points
    20
    Par défaut Utilisation Mémoire d'une application
    Bonjour, j'ai farfouillé dans le forum mais n'ai pas trouvé ce qui m'intéresse vraiment.

    Voilà, je veux faire un service sous delphi qui tourne h24 et je veux pouvoir logger l'évolution de l'utilisation mémoire de mon appli.

    Alors j'ai bien trouvé l'API GlobalMemoryStatus qui me donne l'utilisation générale de la mémoire windows etc mais pas celle de mon appli seul.
    En gros je veux pouvoir récupérer ce qui apparait dans le gestionnaire des taches.

    Je dois pu être loin mais je tourne en rond dans mes recherches, merci de m'aider

  2. #2
    Membre expérimenté

    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    685
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 685
    Points : 1 608
    Points
    1 608
    Par défaut
    Si tu veux contrôler les fuites de mémoires, MemCheck est bien et gratuit.
    Sinon, pour "monitorer" uniquement l'évolution de l'occupation mémoire de certaines instances de classes, j'ai fait un objet pour gérer ça... Je peux lke poster si ca t'interesse.
    "It's more fun to compute !"

  3. #3
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut Re: Utilisation Mémoire d'une application
    Citation Envoyé par scorplex
    Voilà, je veux faire un service sous delphi qui tourne h24 et je veux pouvoir logger l'évolution de l'utilisation mémoire de mon appli.
    Bon, je présuppose que tu es familier avec l'API Win32...
    Pourquoi n'utilises-tu pas un tas privé (HeapCreate), puis des allocations au sein de ce tas via GlobalAlloc ? Au moins, ça te laisse 100% de contrôle...
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 25
    Points : 20
    Points
    20
    Par défaut
    Si tu veux contrôler les fuites de mémoires, MemCheck est bien et gratuit.
    Y a un peu de ça mais je veux aussi voir l'utilisation en pointe de mémoire de mon service et gérer des alarmes en cas d'utilisation trop gourmande. Ton objet m'intéresse donc pas mal !!

    Bon, je présuppose que tu es familier avec l'API Win32
    Ben pas plus que ça en fait et j'avoue ne pas avoir saisi grand chose lol mais je vais chercher sur ce thème

  5. #5
    Membre chevronné
    Avatar de Clorish
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 474
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 474
    Points : 2 158
    Points
    2 158
    Par défaut
    Sinon, pour "monitorer" uniquement l'évolution de l'occupation mémoire de certaines instances de classes, j'ai fait un objet pour gérer ça... Je peux lke poster si ca t'interesse.
    Ca m'interesse aussi.
    JE cherche a faire un monotoring de tout ce qui est creation de variable modifications des contenus, etc .. pour suivre l'evolution d'un log (genre debugger) mais aussi verifier les creation/Destruction d'objet et ce que semble proposer ton unité. Histoire de verifier que le code ecrit est propre.
    On passe du temps a vous repondre, alors soyez sympas, passez du temps ..... a vous relire !
    --
    Pourquoi tant de haine pour cette pauvre aide Delphi ????
    Aiiimezzz laaaaa .... Si-Non-Cham-Pi-Gnon !!!
    --
    Pour plus de Renseignements : Venez me rejoindre sur Msn .... Promis je mords pas

  6. #6
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par scorplex
    Ben pas plus que ça en fait et j'avoue ne pas avoir saisi grand chose lol mais je vais chercher sur ce thème
    Si tu peux attendre ce soir (je n'ai pas les sources sous la main), j'ai un objet Delphi encapsulant ces fonctions et permettant la création "manuelle" d'un tas privé. Le but premier était surtout de pouvoir libérer d'un coup N allocations mémoire (plutôt que de devoir faire une libération manuelle lourde et pénible) pour l'implémentation d'arbres : un tas par arbre = facile à allouer/libérer, et surtout RAPIDE.
    L'avantage est que tu peux facilement greffer un callback (un évènement, si tu préfères) lors de l'allocation, afin de déterminer la conso mémoire "en temps réel".
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 25
    Points : 20
    Points
    20
    Par défaut
    Pas de souci, je peux bien attendre une peu, je cherche depuis un bon moment, je suis pas à deus jours pret.
    Merci d'avance

  8. #8
    Membre expérimenté

    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    685
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 685
    Points : 1 608
    Points
    1 608
    Par défaut
    Rien de magique, l'objet sert juste à voir le nombre d'instances d'objets et leur taille en mémoire. Je m'en suis servi pour monitorer une appli avec l'objet TJvScope (le compo de la JVCL qui affiche de belles courbes...)

    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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    unit InstancesMngr;
     
    interface
     
    uses SysUtils, Classes, Contnrs;
     
    //debug unit - Adrien Reboisson
    //
    //
     
    type
      TThObjectClass = class of TObject;
     
      TThInstanceWatch = class
      private
        FInstances: Cardinal;
        FInstanceSize: Cardinal;
        FName: string;
        FInstancesMax: Cardinal;
      public
       constructor Create(AName: string; AInstanceSize: Integer);
       procedure IncInstances;
       procedure DecInstances;
       function CountInstances: Cardinal;
       function MaxCountedInstances: Cardinal;
       function GetSizeAllocated : Cardinal;
       function GetMaxSizeAllocated: Cardinal;
       property ObjectInstanceSize: Cardinal read FInstanceSize;
       property Name: string read FName;
      end;
     
      TThInstGlobalStatus = record
         CurrentInstancesWatched: Integer;
         CurrentInstancesSize: Integer;
         MaxInstancesWatched: Integer;
         MaxInstancesSize: Integer;
      end;
     
      TThInstMngrStatusEvent = procedure (ASender: TObject; AInstanceWatch: TThInstanceWatch) of object;
      TThInstMngrGlobalStatusEvent = procedure (ASender: TObject; AGlobalInfo : TThInstGlobalStatus) of object;
     
      TThInstancesManager = class (TThLockObject)
      private
        FInstancesList: TObjectList;
        FOnStatus: TThInstMngrStatusEvent;
        FMaxInstancesWatched: Cardinal;
        FMaxinstancesSizeWatched: Cardinal;
        FOnGlobalStatus: TThInstMngrGlobalStatusEvent;
        FActive: Boolean;
        function Find(const S: ShortString; var Index: Integer): Boolean;
      public
        constructor Create;
        destructor Destroy; override;
        procedure InstanceCreated(AObject: TObject);
        procedure InstanceFreed(AObject: TObject);
        function GetInstancesStat(AClassName: string): TThInstanceWatch; overload;
        function GetInstancesStat(AClass: TThObjectClass): TThInstanceWatch; overload;
        function GetMaxInstancesWatched: Cardinal;
        function GetMaxInstancesSizeWatched: Cardinal;
        property OnStatus: TThInstMngrStatusEvent read FOnStatus write FOnStatus;
        property OnGlobalStatus: TThInstMngrGlobalStatusEvent read FOnGlobalStatus write FOnGlobalStatus;
        procedure GetWatchResults;
        property Active: Boolean read FActive write FActive;
      end;
     
      procedure iwInstanceCreated(AObject: TObject);
      procedure iwInstanceDestroyed(AObject: TObject);
      procedure iwRegisterStatusProcs(AInstProc: TThInstMngrStatusEvent;
        AGlobProc : TThInstMngrGlobalStatusEvent);
      procedure iwDoCallBack;
      procedure iwStartWatch;
      procedure iwEndWatch;
     
    implementation
     
     
    var
      GInstancesMngr : TThInstancesManager= nil;
     
    procedure CheckManagerCreated;
    begin
      if not Assigned(GInstancesMngr) then
        GInstancesMngr := TThInstancesManager.Create;
    end;
     
    procedure iwStartWatch;
    begin
      CheckManagerCreated;
      GInstancesMngr.Active := True;
    end;
     
    procedure iwEndWatch;
    begin
      CheckManagerCreated;
      GInstancesMngr.Active := False;
    end;
     
    procedure iwInstanceCreated(AObject: TObject);
    begin
      CheckManagerCreated;
      GInstancesMngr.InstanceCreated(AObject);
    end;
     
    procedure iwRegisterStatusProcs(AInstProc: TThInstMngrStatusEvent;
        AGlobProc : TThInstMngrGlobalStatusEvent);
    begin
      CheckManagerCreated;
      GInstancesMngr.OnStatus := AInstProc;
      GInstancesMngr.OnGlobalStatus := AGlobProc;
    end;
     
    procedure iwInstanceDestroyed(AObject: TObject);
    begin
      CheckManagerCreated;
      GInstancesMngr.InstanceFreed(AObject);
    end;
     
    procedure iwDoCallBack;
    begin
      CheckManagerCreated;
      GInstancesMngr.GetWatchResults;
    end;
     
    { TThInstancesManager }
     
    function TThInstancesManager.Find(const S: ShortString; var Index: Integer): Boolean;
    var
      L, H, I : Integer;
      C: Integer;
    begin
      Result := False;
      L := 0;
      H := FInstancesList.Count - 1;
      while L <= H do
      begin
        I := (L + H) shr 1;
        C := AnsiCompareStr(TThInstanceWatch(FInstancesList[I]).Name, S);
        if C < 0 then L := I + 1 else
        begin
          H := I - 1;
          if C = 0 then
          begin
            Result := True;
            L := I;
            Break;
          end;
        end;
      end;
      Index := L;
    end;
     
     
    constructor TThInstancesManager.Create;
    begin
      inherited;
      FInstancesList := TObjectList.Create;
      FMaxInstancesWatched := 0;
      FMaxinstancesSizeWatched := 0;
      FActive := False;
    end;
     
    destructor TThInstancesManager.Destroy;
    begin
      FInstancesList.Free;
      inherited;
    end;
     
    procedure TThInstancesManager.InstanceCreated(AObject: TObject);
    var
      LWatch: TThInstanceWatch;
      I : Integer;
    begin
      if Active then
      begin
        Lock;
        try
          if Find(AObject.ClassType.ClassName, I) then
            LWatch := TThInstanceWatch(FInstancesList[I])
          else
          begin
            LWatch := TThInstanceWatch.Create(AObject.ClassType.ClassName,
              AObject.ClassType.InstanceSize);
            FInstancesList.Insert(I, LWatch);
          end;
          LWatch.IncInstances;
        finally
          Unlock;
        end;
      end;
    end;
     
    procedure TThInstancesManager.InstanceFreed(AObject: TObject);
    var
      I : Integer;
    begin
     if Active then
     begin
       Lock;
       try
         if Find(AObject.ClassType.ClassName, I) then
           TThInstanceWatch(FInstancesList[i]).DecInstances
         else
           raise Exception.CreateFmt('Instance never watched : %s', [AObject.ClassType.ClassName]);
       finally
         Unlock;
       end;
     end;
    end;
     
    function TThInstancesManager.GetInstancesStat(
      AClassName: string): TThInstanceWatch;
    var
      I: Integer;
    begin
      Result := nil;
      Lock;
      try
        if Find(AClassName, I) then
          Result := TThInstanceWatch(FInstancesList[I]);
      finally
         Unlock;
      end;
    end;
     
    function TThInstancesManager.GetInstancesStat(
      AClass: TThObjectClass): TThInstanceWatch;
    begin
      Result := GetInstancesStat(AClass.ClassName);
    end;
     
    procedure TThInstancesManager.GetWatchResults;
    var
     I: integer;
     N, S: Cardinal;
     LWatch: TThInstanceWatch;
     LStatus: TThInstGlobalStatus;
    begin
     if (Active) and (not ((@FOnStatus = nil) and (@FOnGlobalStatus = nil))) then
     begin
       N := 0;
       S := 0;
       Lock;
       try
          for I := 0 to Pred(FInstancesList.Count) do
          begin
            LWatch := TThInstanceWatch(FInstancesList[I]);
            Inc(N, LWatch.CountInstances);
            Inc(S, LWatch.GetSizeAllocated);
            if Assigned(FOnStatus) then
              FOnStatus(Self, LWatch);
            if N > FMaxInstancesWatched then
              FMaxInstancesWatched := N;
            if S > FMaxinstancesSizeWatched then
              FMaxinstancesSizeWatched := S;
          end;
          if Assigned (FOnGlobalStatus) then
          begin
            LStatus.CurrentInstancesWatched := N;
            LStatus.CurrentInstancesSize := S;
            LStatus.MaxInstancesWatched := FMaxInstancesWatched;
            LStatus.MaxInstancesSize := FMaxinstancesSizeWatched;
            FOnGlobalStatus(Self, LStatus);
          end;
       finally
         Unlock;
       end;
     end;
    end;
     
    function TThInstancesManager.GetMaxInstancesSizeWatched: Cardinal;
    begin
      Result := FMaxinstancesSizeWatched;
    end;
     
    function TThInstancesManager.GetMaxInstancesWatched: Cardinal;
    begin
      Result := FMaxInstancesWatched;
    end;
     
    { TThInstanceWatch }
     
    function TThInstanceWatch.CountInstances: Cardinal;
    begin
      Result := FInstances;
    end;
     
    constructor TThInstanceWatch.Create(AName: string; AInstanceSize: Integer);
    begin
      inherited Create;
      FName := AName;
      FInstanceSize := AInstanceSize;
      FInstances := 0;
      FInstancesMax := 0;
    end;
     
    procedure TThInstanceWatch.DecInstances;
    begin
      Dec(FInstances);
    end;
     
    function TThInstanceWatch.GetMaxSizeAllocated: Cardinal;
    begin
      Result := FInstancesMax * FInstanceSize;
    end;
     
    function TThInstanceWatch.GetSizeAllocated: Cardinal;
    begin
      Result := FInstances * FInstanceSize;
    end;
     
    procedure TThInstanceWatch.IncInstances;
    begin
     Inc(FInstances);
     if FInstances > FInstancesMax then
       Inc(FInstancesMax);
    end;
     
    function TThInstanceWatch.MaxCountedInstances: Cardinal;
    begin
      Result := FInstancesMax;
    end;
     
    initialization
      iwStartWatch;
     
    finalization
      if Assigned(GInstancesMngr) then
        GInstancesMngr.Free;
     
    end.
    Rien d'automagique, encore, dans les constructeurs des objets à surveiller, il faut appeller :
    iwInstanceCreated(Self);
    et les destructeurs :
    iwInstanceDestroyed(Self);

    L'objet fonctionne par callbacks. Deux callbacks sont appellés : une première pour chaque instance enregistrée, une seconde pour un bilan global des instances en mémoire. On passe par iwRegisterStatusProcs pour enregistrer les procédures.

    iwRegisterStatusProcs(InstancesWatchEvent, InstancesWatchStatus);

    Il faut appeller iwDoCallback lorsqu'on veut récupérer les infos. Moi je le fais dans un timer :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    procedure TMainForm.InstancesTrackerTimerTimer(Sender: TObject);
    begin
      if tsDebugMemory.Visible then
        iwDoCallBack;
    end;
    Pour chaque instance enregistrée, l'évènement lié est appellé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    procedure TMainForm.InstancesWatchEvent(ASender: TObject;
      AInstanceWatch: TThInstanceWatch);
    begin
      MemoInstances.Lines.Add(Format('Object: %s, %d instances, %d bytes, %d bytes allocated max', [AInstanceWatch.Name,
        AInstanceWatch.CountInstances, AInstanceWatch.GetSizeAllocated, AInstanceWatch.GetMaxSizeAllocated]))
    end;
    Idem :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    procedure TMainForm.InstancesWatchStatus(ASender: TObject;
      AStatus: TThInstGlobalStatus);
    begin
     MemoInstances.Lines.Add(Format('Objects watched: %d (%d bytes) - Max %d objects, %d bytes', [AStatus.CurrentInstancesWatched,
     AStatus.CurrentInstancesSize, AStatus.MaxInstancesWatched, AStatus.MaxInstancesSize]));
     if AStatus.MaxInstancesWatched > 0 then
       Scope.Lines.Lines[0].Position := Round((AStatus.CurrentInstancesWatched / AStatus.MaxInstancesWatched) * 100);
     if AStatus.MaxInstancesSize > 0 then
       Scope.Lines.Lines[1].Position := Round((AStatus.CurrentInstancesSize / AStatus.MaxInstancesSize) * 100);
    end;
    Bon, ca reste manuel est assez bricolo mais pour le débuggage ca peut parfois aider.
    "It's more fun to compute !"

  9. #9
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Je devrais intégrer cette classe à mon unité LakUtils très bientôt. Il est possible qu'il y aie encore quelques bugs dedans, car je ne l'ai pas encore complètement testée. Cependant, elle est fonctionnelle

    Le code est garanti pour Delphi 7 : pour les autres versions, une adaptation minime sera peut-être nécessaire.

    N'hésites pas à demander si tu ne vois pas comment l'utiliser.

    Déclaration de la classe :
    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
    55
    56
    57
    58
    59
    60
    61
        // Objet d'allocation de mémoire avec GC basique.
        // Cet objet encapsule l'API Win32 HeapCreate et ses fonctions associées.
        // La destruction d'un tas entraîne la destruction des éléments alloués.
        THeapUtils = Class
     
        Protected
     
          FHandle : THandle  ;  // Handle privé pour instance unique.
          FFlags  : Cardinal ;  // Flags communs.
     
          // Accesseurs
          function GetMutexed: Boolean; Platform ;
          procedure SetMutexed(const Value: Boolean); Platform ;
     
        Public
     
          // Constructeur.
          Constructor Create ; Platform ;
     
          // Destructeur. Si un tas local a été alloué, il sera détruit.
          Destructor Destroy ; Override ; Platform ;
     
          // Indique si les fonctions d'accès au tas utilisent ou pas un mutex privé.
          Property Mutexed : Boolean Read GetMutexed Write SetMutexed Default False ;
     
          // Initialise un nouveau tas privé.
          // Si MaxSize est nul, le tas n'est pas limité en taille.
          // Le paramètre Default permet de ne pas avoir à gérer le handle du tas.
          // Si ce paramètre est omis, alors tous les appels aux méthodes de l'objet
          // qui ignoreront le paramètre Heap utiliseront ce tas.
          // En contrepartie, il n'est pas possible d'allouer plusieurs tas par défaut.
          // Si l'on tente de créer un nouveau tas par défaut, le tas courant est
          // remplacé ET IL EST DETRUIT.
          Function HeapCreate (
                   Const KbStartSize : Cardinal        ;   // Taille initiale du tas, en KILOOCTETS.
                   Const KbMaxSize   : Cardinal = 0    ;   // Taille maximale du tas, en KILOOCTETS : 0 = pas de limite.
                   Const Default     : Boolean  = True     // Tas par défaut ?
                    ) : THandle ; Platform ;
     
          // Alloue de la mémoire sur le tas.
          Function Alloc ( Const Size : Cardinal ; Const Heap : THandle = INVALID_HANDLE_VALUE ) : Pointer ; Platform ;
     
          // Alloue de la mémoire initialisée sur le tas.
          // Le contenu du bloc est mis à zéro.
          Function AllocZero ( Const Size : Cardinal ; Const Heap : THandle = INVALID_HANDLE_VALUE ) : Pointer ; Platform ;
     
          // Rélloue de la mémoire sur le tas.
          Procedure ReAlloc ( Var Block : Pointer ; Const NewSize : Cardinal ; Const Heap : THandle = INVALID_HANDLE_VALUE ) ; Platform ;
     
          // Réalloue de la mémoire initialisée sur le tas.
          // Si de la mémoire est ajoutée, le contenu des nouvelles données est mis à zéro.
          Procedure ReAllocZero ( Var Block : Pointer ; Const NewSize : Cardinal ; Const Heap : THandle = INVALID_HANDLE_VALUE ) ; Platform ;
     
          // Libère un bloc alloué.
          // Le pointeur est mis à Nil.
          Procedure Free ( Var Block : Pointer ; Const Heap : THandle = INVALID_HANDLE_VALUE ) ; Platform ;
     
          // Détruit un tas privé.
          Procedure HeapDestroy ( Const Heap : THandle = INVALID_HANDLE_VALUE ) ; Platform ;
     
        End Platform ;
    Implémentation :
    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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    { THeapUtils }
     
    function THeapUtils.Alloc(const Size: Cardinal;
      const Heap: THandle): Pointer;
    Var
       H : THandle ;
    begin
         If (Heap=INVALID_HANDLE_VALUE) Then H:=FHandle
                                        Else H:=Heap ;
         Result:=HeapAlloc(H,FFlags,Size);
    end;
     
    function THeapUtils.AllocZero(const Size: Cardinal;
      const Heap: THandle): Pointer;
    Var
       H : THandle ;
    begin
         If (Heap=INVALID_HANDLE_VALUE) Then H:=FHandle
                                        Else H:=Heap ;
         Result:=HeapAlloc(H,HEAP_ZERO_MEMORY Or FFlags,Size);
    end;
     
    constructor THeapUtils.Create;
    begin
         Inherited Create;
         FHandle:=INVALID_HANDLE_VALUE;
         Mutexed:=False;
    end;
     
    destructor THeapUtils.Destroy;
    begin
         If (FHandle<>INVALID_HANDLE_VALUE) Then
            HeapDestroy;
         Inherited;
    end;
     
    procedure THeapUtils.HeapDestroy(const Heap: THandle);
    Var
       H : THandle ;
    begin
         If (Heap=INVALID_HANDLE_VALUE) Then H:=FHandle
                                        Else H:=Heap ;
         Win32Check(Windows.HeapDestroy(H));
         // Penser au cas où le tas est invalide...
         If (Heap=INVALID_HANDLE_VALUE) Then
            FHandle:=INVALID_HANDLE_VALUE;
    end;
     
    procedure THeapUtils.Free(var Block: Pointer; const Heap: THandle);
    Var
       H : THandle ;
    begin
         If (Heap=INVALID_HANDLE_VALUE) Then H:=FHandle
                                        Else H:=Heap ;
         Win32Check(Windows.HeapFree(H,FFlags,Block));
         Block:=Nil;
    end;
     
    function THeapUtils.HeapCreate(const KbStartSize: Cardinal; const KbMaxSize: Cardinal; const Default: Boolean): THandle;
    begin
         Result:=Windows.HeapCreate(FFlags,1024*KbStartSize,1024*KbMaxSize);
         // Demande d'unicité => on stocke le handle dans la classe.
         If Default Then
            Begin
            If (FHandle<>INVALID_HANDLE_VALUE) Then
               Self.HeapDestroy(FHandle);
            FHandle:=Result ;
            End;
    end;
     
    procedure THeapUtils.ReAlloc(var Block: Pointer; const NewSize: Cardinal; const Heap: THandle);
    Var
       H : THandle ;
    begin
         If (Heap=INVALID_HANDLE_VALUE) Then H:=FHandle
                                        Else H:=Heap ;
         Block:=Windows.HeapReAlloc(H,FFlags,Block,NewSize);
    end;
     
    procedure THeapUtils.ReAllocZero(var Block: Pointer;
      const NewSize: Cardinal; const Heap: THandle);
    Var
       H : THandle ;
    begin
         If (Heap=INVALID_HANDLE_VALUE) Then H:=FHandle
                                        Else H:=Heap ;
         Block:=Windows.HeapReAlloc(H,HEAP_ZERO_MEMORY Or FFlags,Block,NewSize);
    end;
     
    function THeapUtils.GetMutexed: Boolean;
    begin
         Result:=(FFlags And HEAP_NO_SERIALIZE)=0;
    end;
     
    procedure THeapUtils.SetMutexed(const Value: Boolean);
    begin
         If (Value) Then FFlags:=HEAP_GENERATE_EXCEPTIONS
                    Else FFlags:=HEAP_GENERATE_EXCEPTIONS Or HEAP_NO_SERIALIZE ;
    end;
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

Discussions similaires

  1. Utiliser ssh dans une application java
    Par Samanta dans le forum Sécurité
    Réponses: 12
    Dernier message: 28/02/2007, 16h30
  2. Mesurer l'utilisation mémoire d'une carte graphique
    Par Harry dans le forum Composants
    Réponses: 1
    Dernier message: 26/02/2007, 17h20
  3. Réponses: 4
    Dernier message: 08/12/2006, 16h24
  4. Utiliser Remoting dans une application web
    Par loran974 dans le forum Flash
    Réponses: 1
    Dernier message: 04/10/2006, 09h48
  5. Réponses: 11
    Dernier message: 13/01/2006, 15h30

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