Forum Delphi.cz

Delphi => FireDAC => Téma založeno: maca2me 10-07-2018, 09:21:43

Název: Při použití FireDAC roste paměť v linuxu (ubuntu 18.04 LTS a 16.04 LTS)
Přispěvatel: maca2me 10-07-2018, 09:21:43
Ahoj,

při vývoji (Rad studio 10.2) jsme narazili na problém při použití poolu connections pro Firebird 2.5 z vícevláknové aplikace. Na linuxu roste paměť a to poměrně vysokým tempem několik MB za minutu při normálním provozu. Na Windows se chová dobře, resp. paměť zůstává konstantní. Udělali jsme si i malý testovací prográmek, viz níže a chová se jinak na Windows a na Ubuntu. Podle článků je použití poolu při přístupu k DB z vícevláknové aplikace správné. Řešíme již několik dní a zatím bez úspěchu.

Kód: [Vybrat]
program Project1;
 

{$APPTYPE CONSOLE}
 

{$R *.res}
 

uses
  System.SysUtils, Classes, FireDAC.Stan.Intf, FireDAC.Stan.Option,
  FireDAC.Stan.Error, FireDAC.UI.Intf, FireDAC.Phys.Intf, FireDAC.Stan.Def,
  FireDAC.Stan.Pool, FireDAC.Stan.Async, FireDAC.Phys, FireDAC.ConsoleUI.Wait,
  Data.DB, FireDAC.Comp.Client, FireDAC.Phys.FB, FireDAC.Phys.FBDef,
  FireDAC.Stan.Param, FireDAC.DatS, FireDAC.DApt.Intf, FireDAC.DApt,
  FireDAC.Comp.DataSet, FireDAC.Comp.UI;
 

var
  gParams: TStringList;
  FDPhysFBDriverLink1: TFDPhysFBDriverLink;
  FDManager: TFDManager;
  gFDConnection: TFDConnection;
  gFDQuery: TFDQuery;
begin
  try
    {$IFDEF LINUX}
    FDPhysFBDriverLink1 := TFDPhysFBDriverLink.Create(nil);
    FDPhysFBDriverLink1.VendorLib := '/usr/lib/x86_64-linux-gnu/libfbclient.so.2';
    {$ENDIF}
    FDManager := TFDManager.Create(nil);
    gParams := TStringList.Create;
    try
    //gParams.Add('Database=/var/HavisDatabase/HAVISIII.FDB');
    gParams.Add('Database=C:\E\Starmon\Projekty\HAVISIII\AppService\DB\HAVISIII.FDB');
    gParams.Add('User_Name=SYSDBA');
    gParams.Add('Password=masterkey');
    gParams.Add('Pooled=True');
    gParams.Add('POOL_MaximumItems=3');  // 300 současných přístupů do DB
    gParams.Add('POOL_ExpireTimeout=30000');
    gParams.Add('POOL_CleanupTimeout=90000');
    gParams.Add('CharacterSet=UTF8');
    FDManager.AddConnectionDef('Firebird_pooled1', 'FB', gParams);
 

 

    while True do
    begin
      gFDConnection := TFDConnection.Create(nil);
      gFDQuery := TFDQuery.Create(nil);
      try
        gFDConnection.ConnectionDefName := 'Firebird_pooled1';
        gFDQuery.Connection := gFDConnection;
        gFDConnection.Connected := True;
        gFDQuery.SQL.Text := 'SELECT * FROM SWITCHBOARDS';
        gFDQuery.Open();
        gFDQuery.Last;
      finally
        gFDQuery.Close;
        gFDConnection.Close;
        gFDQuery.Free;
        gFDConnection.Free;
      end;
      sleep(100);
    end;
    finally
      FDManager.CloseConnectionDef('Firebird_pooled1');
      FDManager.Free;
      gParams.Free;
      {$IFDEF LINUX}
      FDPhysFBDriverLink1.Free;
      {$ENDIF}
    end;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

Uvítám jakékoli rady, na co se zaměřit.

Díky moc
Název: Re:Při použití FireDAC roste paměť v linuxu (ubuntu 18.04 LTS a 16.04 LTS)
Přispěvatel: Radek Červinka 10-07-2018, 10:31:40
Zkus misto
Kód: [Vybrat]
gFDQuery.Free
pouzit

Kód: [Vybrat]
FDFreeAndNil(gFDQuery)
z jednotky FireDAC.Stan.Util
Název: Re:Při použití FireDAC roste paměť v linuxu (ubuntu 18.04 LTS a 16.04 LTS)
Přispěvatel: maca2me 10-07-2018, 10:32:16
Používáme příkaz top. Pro jiný SW (stejné RAD studio jen neni přístup k Firebird) se chová normálně - tzn. paměť roste ale pak se uvolní. Problém jsme vysledovali až k připojení k Firebird. Vyzkoušeli jsme i malý prográmek s getmem a freemem a to se zobrazuje v top korektně - alokuje a dealokuje.
Název: Re:Při použití FireDAC roste paměť v linuxu (ubuntu 18.04 LTS a 16.04 LTS)
Přispěvatel: Radek Červinka 10-07-2018, 10:34:23
Případně gFDQuery := nil; Pamatuj, že na Linuxu je ARC, tj. Free je trochu jiné.

Kód: [Vybrat]
procedure TObject.Free;
begin
// under ARC, this method isn't actually called since the compiler translates
// the call to be a mere nil assignment to the instance variable, which then calls _InstClear
{$IFNDEF AUTOREFCOUNT}
  if Self <> nil then
    Destroy;
{$ENDIF}
end;

Název: Re:Při použití FireDAC roste paměť v linuxu (ubuntu 18.04 LTS a 16.04 LTS)
Přispěvatel: Radek Červinka 10-07-2018, 10:40:45
Vyzkoušeli jsme i malý prográmek s getmem a freemem a to se zobrazuje v top korektně - alokuje a dealokuje.

GetMem a FreeMem jde mimo ARC.
Název: Re:Při použití FireDAC roste paměť v linuxu (ubuntu 18.04 LTS a 16.04 LTS)
Přispěvatel: Radek Červinka 10-07-2018, 11:27:00
A prirazeni reference te promenne neznici puvodne prirazenou?

Kód: Delphi [Vybrat]
  1. var
  2.   MyObject: TMyBaseObject;
  3. begin
  4.   MyObject := TMyFirstObject.Create;
  5.   MyObject := TMySecondObject.Create; // znici se pred timto prirazenim instance TMyFirstObject?
  6. end;

No to jo, pokud na ni nic jineho neodkazuje, v našem případě by to mohl být např. Connection (to tak hadam).
A na connection treba taky neco odkazuje. atd.

Zmizi to, az to vypadne všechno ze scope.

Ale jak rikam, vzhledem k tomu, jak je FireDac postaven, a vzhledem k tomu, jak je napsan FDFreeAndNil tak nejak tipuji, že toto by mohl být problémem (hlavu ale na to nedám) a nic jiného mne nenapadá - kromě leaku ve FireDacu (https://quality.embarcadero.com/browse/RSP-17331 (https://quality.embarcadero.com/browse/RSP-17331), https://quality.embarcadero.com/browse/RSP-17428 (https://quality.embarcadero.com/browse/RSP-17428).



Název: Re:Při použití FireDAC roste paměť v linuxu (ubuntu 18.04 LTS a 16.04 LTS)
Přispěvatel: maca2me 10-07-2018, 12:00:55
Zkus misto
Kód: [Vybrat]
gFDQuery.Free
pouzit

Kód: [Vybrat]
FDFreeAndNil(gFDQuery)
z jednotky FireDAC.Stan.Util

Vyzkoušeli jsme na tom malém prográmku a vypadá to, že funguje v pořádku. Teď implementujeme do projektu. Moc díky za nakopnutí. Vyvíjíme společně pod Windows i pod Linux, tak občas narazíme na nějaké takové problémy. Ještě bych měl dotaz k tématu - pokud tedy je v linuxu ARC a my chceme vyvíjet pro oba systémy, co by bylo nejlepší používat pro uvolnění? Neradi bychom všude cpali podmíněný překlad. Mohlo by lépe fungovat společně FreeAndNil? Teď myslím u obecných objektů. Pro FD budeme používat FDFreeAndNil. Díky
Název: Re:Při použití FireDAC roste paměť v linuxu (ubuntu 18.04 LTS a 16.04 LTS)
Přispěvatel: Radek Červinka 10-07-2018, 12:11:29
Neradi bychom všude cpali podmíněný překlad. Mohlo by lépe fungovat společně FreeAndNil? Teď myslím u obecných objektů. Pro FD budeme používat FDFreeAndNil. Díky

FDFreeAndNil můžete používat kde chcete, je to psané univerzálně.
Název: Re:Při použití FireDAC roste paměť v linuxu (ubuntu 18.04 LTS a 16.04 LTS)
Přispěvatel: Radek Červinka 10-07-2018, 12:23:32
Aby nedoslo k nedorozumnení: samozrejme muzete pouzivat Free, ARC zaruci, ze se objekt uvolni az neni treba (zjednodusene - pozor na kruhove reference atd.). To FDFreeAndNil je vynuceni uvolneni.
Název: Re:Při použití FireDAC roste paměť v linuxu (ubuntu 18.04 LTS a 16.04 LTS)
Přispěvatel: maca2me 10-07-2018, 12:53:57
Aby nedoslo k nedorozumnení: samozrejme muzete pouzivat Free, ARC zaruci, ze se objekt uvolni az neni treba (zjednodusene - pozor na kruhove reference atd.). To FDFreeAndNil je vynuceni uvolneni.

Ok. Díky moc. Snad to bude teď fungovat v pořádku.