Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.175 Beiträge
 
Delphi 12 Athens
 
#13

AW: Clientdataset Speicherfreigabe

  Alt 2. Jun 2022, 08:23
Hab meinen Testcode noch etwas erweitert (erstmal alles, was an Property und Methoden im ClientDataSet zu sehen war, nach dem Delete rein, gesehen es geht und dann schrittweise alles Unnütze wieder raus)
und eine Teillösung gefunden.

Es gibt den Speicher nicht komplett frei, aber zumindesten das Log schein weg zu sein.
(beim nächsten Add und Delete wird kein neuer Speicher hinzugefügt oder freigegeben)
  • LogChanges:=False half nichts
  • CancelUpdates und MergeChangeLog hilft auch nicht
  • aber EmptyDataSet nach oder besser noch anstatt dem While-Delete ist hier die Lösung
    • und es ist sogar um Längen schneller


Delphi-Quellcode:
{$OVERFLOWCHECKS OFF}

uses
  System.StrUtils, Data.DB, Datasnap.DBClient;

procedure TForm8.FormCreate(Sender: TObject);
var
  CDS: TClientDataSet;
  Mem: UInt64;
procedure ShowState;
  var
    GStatus: TMemoryStatusEx;
    MMState: TMemoryManagerState;
  begin
    //Memo1.Lines.Add(' Records ' + CDS.RecordCount.ToString);

    GStatus.dwLength := SizeOf(GStatus);
    GlobalMemoryStatusEx(GStatus);

    GetMemoryManagerState(MMState);
    var FastMM: Int64 := 0;
    for var i := 0 to High(MMState.SmallBlockTypeStates) do
      Inc(FastMM, MMState.SmallBlockTypeStates[i].UseableBlockSize * MMState.SmallBlockTypeStates[i].AllocatedBlockCount);
    Inc(FastMM, MMState.TotalAllocatedMediumBlockSize);
    Inc(FastMM, MMState.TotalAllocatedLargeBlockSize);

    Memo1.Lines.Add(Format(' Memory %d%% %.2nm %s%.2nm / %.2nm', [
      GStatus.dwMemoryLoad, Int64(GStatus.ullTotalVirtual - GStatus.ullAvailVirtual) / 1048576,
      IfThen(Mem < GStatus.ullAvailVirtual, '', '+'), Int64(Mem - GStatus.ullAvailVirtual) / 1048576,
      FastMM / 1048576
    ]));
    Mem := GStatus.ullAvailVirtual;
  end;
begin
  Mem := 0;
  CDS := TClientDataSet.Create(Self);
  CDS.FieldDefs.Add('TEST1', ftString, 500);
  CDS.FieldDefs.Add('TEST2', ftString, 500);
  CDS.FieldDefs.Add('TEST3', ftString, 500);
  CDS.CreateDataSet;
  CDS.LogChanges := False;

  for var L := 1 to 199 do
    try
      Memo1.Lines.Add(L.ToString);
      //Memo1.Lines.Add('Add');
      for var i := 1 to 9999 do begin
        CDS.Append;
        CDS.FieldByName('TEST1').AsString := Random(MaxInt).ToString;
        CDS.FieldByName('TEST2').AsString := Random(MaxInt).ToString;
        CDS.FieldByName('TEST3').AsString := Random(MaxInt).ToString;
        CDS.Post;
      end;
      ShowState;

      //Memo1.Lines.Add('Delete');
      {$IF false}
      while CDS.RecordCount > 0 do
        CDS.Delete;
      {$ELSE}
      CDS.EmptyDataSet;
      {$IFEND}
      ShowState;
    except
      on E: Exception do begin
        Memo1.Lines.Add(L.ToString + ' : ' + E.Message);
        ShowState;
        Break;
      end;
    end;
end;
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu ( 2. Jun 2022 um 08:30 Uhr)
  Mit Zitat antworten Zitat