Autor Téma: Při použití FireDAC roste paměť v linuxu (ubuntu 18.04 LTS a 16.04 LTS)  (Přečteno 5844 krát)

Offline maca2me

  • Nováček
  • *
  • Příspěvků: 24
  • Karma: 1
    • Verze Delphi: 10.2
Excellent
Rated 1 time
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
Neexistují hloupé otázky ale jen hloupé odpovědi.

100595

  • Host
Na linuxu roste paměť a to poměrně vysokým tempem několik MB za minutu při normálním provozu.

Cim merite tu spotrebu pameti? Ptam se protoze se mohlo stat ze Posix/64 memory manager jen oznacil bloky pameti jako volne ale fyzicky je nevratil OS k vyuziti.

Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 3299
  • Karma: 112
    • Verze Delphi: D2007, DXE + 2 poslední
    • O Delphi v češtině
Zkus misto
Kód: [Vybrat]
gFDQuery.Free
pouzit

Kód: [Vybrat]
FDFreeAndNil(gFDQuery)
z jednotky FireDAC.Stan.Util
Embarcadero MVP - Czech republic

Offline maca2me

  • Nováček
  • *
  • Příspěvků: 24
  • Karma: 1
    • Verze Delphi: 10.2
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.
Neexistují hloupé otázky ale jen hloupé odpovědi.

Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 3299
  • Karma: 112
    • Verze Delphi: D2007, DXE + 2 poslední
    • O Delphi v češtině
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;

Embarcadero MVP - Czech republic

Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 3299
  • Karma: 112
    • Verze Delphi: D2007, DXE + 2 poslední
    • O Delphi v češtině
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.
Embarcadero MVP - Czech republic

100600

  • Host
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;


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;

Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 3299
  • Karma: 112
    • Verze Delphi: D2007, DXE + 2 poslední
    • O Delphi v češtině
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-17428.



Embarcadero MVP - Czech republic

Offline maca2me

  • Nováček
  • *
  • Příspěvků: 24
  • Karma: 1
    • Verze Delphi: 10.2
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
Neexistují hloupé otázky ale jen hloupé odpovědi.

Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 3299
  • Karma: 112
    • Verze Delphi: D2007, DXE + 2 poslední
    • O Delphi v češtině
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ě.
Embarcadero MVP - Czech republic

Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 3299
  • Karma: 112
    • Verze Delphi: D2007, DXE + 2 poslední
    • O Delphi v češtině
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.
Embarcadero MVP - Czech republic

Offline maca2me

  • Nováček
  • *
  • Příspěvků: 24
  • Karma: 1
    • Verze Delphi: 10.2
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.
Neexistují hloupé otázky ale jen hloupé odpovědi.