TidBytes как почистить?

cptngrb
Дата: 12.09.2019 16:00:14
Доброго времени суток.

Есть у меня процедура отправки udp пакетов

var
 Pack: TidByte;
begin
  ...
  UClient.SendBuffer(IPaddr, IPport, Pack);
  Pack:= nil;
 ...
end;


И менеджер памяти Windows мне говорит, что память не чиститься. Но у динамических массивов присвоение nil равносильно уничтожению или я не прав?
Alexander Zuev
Дата: 12.09.2019 16:04:30
Это ты с интерфейсами перепутал. Используй SetLength в 0.
X-Cite
Дата: 12.09.2019 16:05:04
Динамический массив сам почистится при выходе из метода..
Ну или SetLength(Pack, 0);
cptngrb
Дата: 12.09.2019 16:07:10
X-Cite, в доках написано, что SetLength и nil однозначны
X-Cite
Дата: 12.09.2019 16:30:16
Ну раз менеджер памяти говорит что не чистится...
А ReportMemoryLeaksOnShutdown := True не говорит об утечках при закрытии, то память у вас не утекает, а накапливается и не освобождается вовремя
cptngrb
Дата: 12.09.2019 16:32:44
X-Cite, в том то и дело, что fastmem молчит. При выходе я все чищу. Вы правы накапливается и не освобождается вовремя
X-Cite
Дата: 12.09.2019 16:35:15
Значит дело не в Pack:= nil;
Ищите почему вы чистите только при выходе, а не во время работы...
cptngrb
Дата: 13.09.2019 12:37:17
чувствую, что накидаете на вентилятор, но куда деваться
сделан консольное приложение и не пойму почему память не чиститься?

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  FastMM4 in 'FastMM4.pas',
  FastMM4Messages in 'FastMM4Messages.pas',
  System.SysUtils,
  IdGlobal,
  System.Generics.Collections,
  System.SyncObjs;

type
  TRec = packed record
    num1: uint32;
    num2: uint16;
    num3: uint16;
  end;

 PRec = ^TRec;

 TQueueAr = class(TObject)
    private
      FQ: TQueue<TIdBytes>;
      FCS: TCriticalSection;
    public
      constructor Create(const ACapacity: integer); overload;
      destructor Destroy(); override;
      function PopRecord: TIdBytes;
      procedure PushRecord(const AObject: TIdBytes);
      function Count: Integer;
  end;

function TQueueAr.Count: Integer;
begin
  Result:= FQ.Count;
end;

constructor TQueueAr.Create(const ACapacity: integer);
begin
  inherited Create;
  FCS:= TCriticalSection.Create;
  FQ:= TQueue<TIdBytes>.Create;
  FQ.Capacity:= ACapacity;
end;

destructor TQueueAr.Destroy;
begin
  try
    FCS.Free;
    FQ.Free;
  finally
    inherited;
  end;
end;

function TQueueAr.PopRecord: TIdBytes;
begin
  FCS.Enter;
  try
    if FQ.Count = 0  then  Result:= nil
    else Result:= FQ.Dequeue;
  finally
    FCS.Leave;
  end;
end;

procedure TQueueAr.PushRecord(const AObject: TIdBytes);
begin
  FCS.Enter;
  try
    FQ.Enqueue(AObject);
  finally
    FCS.Leave;
  end;
end;

var
  QUEUE_AR: TQueueAr;


procedure SetVal(R: TidBytes; const ANumber1: uint32; const ANumber2, ANumber3: uint16);
begin
    PRec(@R[0])^.num1 := ANumber1;
    PRec(@R[0])^.num2 := ANumber2;
    PRec(@R[0])^.num3 := ANumber3;
end;

procedure Test;
var
 ar: TidBytes;
 i: integer;
begin
  for i := 1 to 1000000 do begin
   SetLength(ar, SizeOf(PRec));
   SetVal(ar, i, 222, 333);
   QUEUE_AR.PushRecord(ar);
  end;
  sleep(1000);
end;

function GetPacket: TIdBytes;
begin
  Result:= nil;
  if QUEUE_AR.count = 0 then exit;
  Result:= QUEUE_AR.PopRecord;
end;

procedure Run;
var
  ar: TIdBytes; 
begin
  ar:= GetPacket;
  if ar= nil then exit;
  ar:= nil;
end;

begin
  ReportMemoryLeaksOnShutdown:= True;
  writeln('заполням очередь');
  readln;   //ОП 6532кБ
  QUEUE_AR:= TQueueAr.Create(1000);
  test;
  writeln('QUEUE_AR.Count = ' + QUEUE_AR.Count.ToString);
  writeln('заполнили очередь');
  readln;  //ОП 298048 кБ
  WriteLn('Clear');
  while QUEUE_AR.Count <> 0 do
  Run; //Удаляли удаляли, а толку ноль
  writeln('QUEUE_AR.Count = ' + QUEUE_AR.Count.ToString);
  writeln('чистим очередь');
  readln;  // //ОП 298048 кБ
  QUEUE_AR.FQ.Clear;
  QUEUE_AR.FQ.TrimExcess;


  Writeln('Для остановки приложения нажмите <Enter>...');
    ReadLn; //289976 кБ
  QUEUE_AR.Free;
end.
cptngrb
Дата: 13.09.2019 12:46:15
а если сделать так, то память не растет.

for i := 1 to 10 do begin

  test;
//  writeln('QUEUE_AR.Count = ' + QUEUE_AR.Count.ToString);
//  writeln('заполнили очередь');
//  readln;  //ОП 298048кБ
//  WriteLn('Clear');
  while QUEUE_AR.Count <> 0 do
  Run; //Удаляли удаляли, а толку ноль

  end;


неужто очередь так гадко себя ведет?
_Vasilisk_
Дата: 13.09.2019 12:52:02
 SetLength(ar, SizeOf(PRec^));