Reduce FireBird memory consumption when closing Dataset

2

I have a Delphi XE7 application that runs on a FireBird 2.5 . When I open a FDTable with a 10,000 records for example, the memory consumption of the FireBird server increases by

asked by anonymous 08.06.2018 / 14:48

2 answers

3

Working with Firebird for a long time, the problem may even be open transactions.

Here we do not usually use FDTable , we use a component of its own, but it's the same thing.

I'll give you an example with TDataSet itself, which is the basis of everything.

var
  vDataSet_Teste : TDataSet;
begin
  vDataSet_Teste := ResultSQL('SELECT ALGUMA_COISA FROM ALGUM_LUGAR');

  while not vDataSet_Teste.Eof do
  begin
    Self.Caption := vDataSet_Teste.FieldByName('ALGUMA_COISA').AsString;
    vDataSet_Teste.Next;
  end;

  vDataSet_Teste.Close;
end;

For this example, consider that ResultSQL returns me a data dataset.

vDataSet_Teste.Close; closes only the ability to read the data, but does not remove it from memory, because in this scenario ResultSQL opened a transaction, consulted the data, and handed it to me for consideration. This way we still have an open transaction, because all DataSet in Delphi is passed as memory, in this case, the dataset that was loaded by ResultSQL still exists and has a transaction with the Server.

The way we found 100% effective was to use a command set for the dataset. If it is a TQuery or a TDataSet :

vDataSet_Teste.Close;
vDataSet_Teste.Free;

Note that in this format we do not use visual components.

    
12.06.2018 / 14:08
-2

You have a routine to reduce memory that is placed inside a timer or after your process:

    procedure TForm1.Timer1Timer(Sender: TObject);
    begin
        if (((GetTickCount - LastTick) / 1000) > 120) or
             (Self.WindowState = wsMinimized) then
        begin
            //Memo1.Lines.Add(FormatFloat('Memory used: ,.# K', CurrentMemoryUsage / 1024));
            TrimAppMemorySize;
            //Memo1.Lines.Add('Reduz memória');
            //Memo1.Lines.Add(FormatFloat('Memory used: ,.# K', CurrentMemoryUsage / 1024));
        end;
    end;

The routine to free memory:

    procedure TrimAppMemorySize;
    var
        MainHandle : THandle;
    begin
        try
            MainHandle := OpenProcess(PROCESS_ALL_ACCESS, false, GetCurrentProcessID) ;
            SetProcessWorkingSetSize(MainHandle, $FFFFFFFF, $FFFFFFFF) ;
            CloseHandle(MainHandle) ;
        except
        end;
        Application.ProcessMessages;
    end;

To check the memory:

    function CurrentMemoryUsage: Cardinal;
    var
        pmc: TProcessMemoryCounters;
    begin
        pmc.cb := SizeOf(pmc) ;
        if GetProcessMemoryInfo(GetCurrentProcess, @pmc, SizeOf(pmc)) then
            Result := pmc.WorkingSetSize
        else
            RaiseLastOSError;
    end;
    
12.06.2018 / 01:17