Autor Téma: firedac problem s pamatou  (Přečteno 4793 krát)

Offline wajco

  • Nováček
  • *
  • Příspěvků: 33
  • Karma: 1
    • Verze Delphi: XE6
firedac problem s pamatou
« kdy: 08-12-2015, 09:41:24 »
Pri pouziti Firedac pri volani fdquery.open v slucke nastava narast pamate konciaci Out of memory.Pri pouziti BDE zabera stale rovnaku pamat. odskusane to je s query umiestnenym na formulari aj s dynamicky vytvaranym query uvolnoenym voalni open. vyseldok je stale rovnaky. viete poradit nejaku property, ktora by to vyriesila, alebo ide o nejaky bug vo firedacu?

Kód: [Vybrat]

 while True do
    begin
      Randomize;
      FDQuery1.SQL.Text := 'select * from tab where i_tab='+Random(182064).tostring;
      inc(i);
      Label14.Caption := i.ToString();
      Application.ProcessMessages;
      Query1.Open;
    end;

Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 2655
  • Karma: 103
    • Verze Delphi: D2007, DXE + 2 poslední
    • O Delphi v češtině
Re:firedac problem s pamatou
« Odpověď #1 kdy: 08-12-2015, 10:37:01 »
FDQuery1  versus Query1?

To je prepis?

Co je to za DB, co je to za driver?
Embarcadero MVP - Czech republic

Offline wajco

  • Nováček
  • *
  • Příspěvků: 33
  • Karma: 1
    • Verze Delphi: XE6
Re:firedac problem s pamatou
« Odpověď #2 kdy: 08-12-2015, 10:41:31 »
FDQuery ma byt vsade, je to TFDQuery, db Informix, ovladac Infx [IBM INFORMIX ODBC DRIVER]
« Poslední změna: 08-12-2015, 10:47:56 od wajco »

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2837
  • Karma: 134
    • Verze Delphi: D2007, XE3, DX10
Re:firedac problem s pamatou
« Odpověď #3 kdy: 08-12-2015, 10:58:12 »
Kód: [Vybrat]

 while True do
    begin
      Randomize;
      FDQuery1.SQL.Text := 'select * from tab where i_tab='+Random(182064).tostring;
      inc(i);
      Label14.Caption := i.ToString();
      Application.ProcessMessages;
      Query1.Open;
    end;
Ja v tom vidim hned nekolik veci, z nichz mi vstava zbytek vlasu na hlave hruzou:
- opakovane uziti Randomize
- rucni matlani SQL dotazu misto pouziti parametrizovaneho dotazu, ktery by v konkretnim pripade umoznil pouzivat stale stejny SQL prikaz a jen menit hodnotu parametru v tele cyklu
- chybna prace s I/O prostredkem -> Po open nenasleduje Close, coz je nejspis pricina toho memory leaku. Spravne by tam melo byt
Kód: Delphi [Vybrat]
  1. Query1.Open;
  2. try
  3.   ...
  4. finally
  5.   Query1.Close;
  6. end
  7.  

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5109
  • Karma: 41
    • Verze Delphi: W10 + Delphi 10.4 professional
Re:firedac problem s pamatou
« Odpověď #4 kdy: 08-12-2015, 11:01:49 »
Nakoľko FireDAC používam, tak ma otázka zaujala. Pozrel som si vlastnosti FDQuery a zaujal ma DirectExecute. Chcel som si niečo o tom prečítať. Ako to vlastne funguje. Ale nič som nenašiel. A help k FireDAC nemá vyhľadávanie.
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline wajco

  • Nováček
  • *
  • Příspěvků: 33
  • Karma: 1
    • Verze Delphi: XE6
Re:firedac problem s pamatou
« Odpověď #5 kdy: 08-12-2015, 11:03:10 »
Kód: [Vybrat]

 while True do
    begin
      Randomize;
      FDQuery1.SQL.Text := 'select * from tab where i_tab='+Random(182064).tostring;
      inc(i);
      Label14.Caption := i.ToString();
      Application.ProcessMessages;
      Query1.Open;
    end;
Ja v tom vidim hned nekolik veci, z nichz mi vstava zbytek vlasu na hlave hruzou:
- opakovane uziti Randomize
- rucni matlani SQL dotazu misto pouziti parametrizovaneho dotazu, ktery by v konkretnim pripade umoznil pouzivat stale stejny SQL prikaz a jen menit hodnotu parametru v tele cyklu
- chybna prace s I/O prostredkem -> Po open nenasleduje Close, coz je nejspis pricina toho memory leaku. Spravne by tam melo byt
Kód: Delphi [Vybrat]
  1. Query1.Open;
  2. try
  3.   ...
  4. finally
  5.   Query1.Close;
  6. end
  7.  

1. close nepomaha, lebo prikaz open v sebe na zaciatku vola close
2. parametrizovane query nepomaha
3. randomize ma byt pred cyklom ano, ale toto tiez nepomoze

tu je upraveny kod, pamat stale narasta

Kód: [Vybrat]
procedure TForm1.Button1Click(Sender: TObject);
var i: Integer;
  q: TFDQuery;
begin
  i:= 0;
  Randomize;
  while True do
    begin
      FDQuery1.SQL.Text := 'select * from tab where i_tab=:p';
      FDQuery1.ParamByName('p').AsInteger := Random(182064);
      inc(i);
      Label14.Caption := i.ToString();
      Application.ProcessMessages;
      FDQuery1.Open();
    end;
end;
« Poslední změna: 08-12-2015, 11:09:17 od wajco »

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5109
  • Karma: 41
    • Verze Delphi: W10 + Delphi 10.4 professional
Re:firedac problem s pamatou
« Odpověď #6 kdy: 08-12-2015, 11:08:42 »
Citace
close nepomaha, lebo prikaz open v sebe na zaciatku vola close
Ale určite sa nevolá, ak nie je dataset aktívny (iba moje presvedčenie).

Z praxe: ak používam parametrizovaný príkaz, tak pred priradením údajov do SQL (parametrov) musím najprv uzavrieť dataset. Ináč sa zmena neprejaví.
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 2655
  • Karma: 103
    • Verze Delphi: D2007, DXE + 2 poslední
    • O Delphi v češtině
Re:firedac problem s pamatou
« Odpověď #7 kdy: 08-12-2015, 11:10:37 »
a kdyz je ten select porad stejny?
select * from tab where i_tab= 10 ?
Embarcadero MVP - Czech republic

Offline wajco

  • Nováček
  • *
  • Příspěvků: 33
  • Karma: 1
    • Verze Delphi: XE6
Re:firedac problem s pamatou
« Odpověď #8 kdy: 08-12-2015, 11:10:55 »
Citace
close nepomaha, lebo prikaz open v sebe na zaciatku vola close
Ale určite sa nevolá, ak nie je dataset aktívny (iba moje presvedčenie).

Z praxe: ak používam parametrizovaný príkaz, tak pred priradením údajov do SQL (parametrov) musím najprv uzavrieť dataset. Ináč sa zmena neprejaví.

z unitu FireDAC.Comp.Client

Kód: [Vybrat]
procedure TFDRdbmsDataSet.Open(const ASQL: String; const AParams: array of Variant;
  const ATypes: array of TFieldType);
var
  i: Integer;
begin
  Close;
  if ASQL <> '' then
    Command.SetCommandText(ASQL,
      not (Command.CommandKind in [skStoredProc, skStoredProcNoCrs, skStoredProcWithCrs]) and
      ResourceOptions.ParamCreate);
  if Command.CommandKind in [skStoredProc, skStoredProcNoCrs, skStoredProcWithCrs] then
    Prepare;
  if Params.BindMode = pbByNumber then
    for i := 0 to Params.Count - 1 do
      Params[i].Position := i + 1;
  for i := Low(ATypes) to High(ATypes) do
    if ATypes[i] <> ftUnknown then
      Params[i].DataType := ATypes[i];
  for i := Low(AParams) to High(AParams) do
    Params[i].Value := AParams[i];
  if not (Command.CommandKind in [skStoredProc, skStoredProcNoCrs, skStoredProcWithCrs]) then
    Prepare;
  Open;
end;

Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 2655
  • Karma: 103
    • Verze Delphi: D2007, DXE + 2 poslední
    • O Delphi v češtině
Re:firedac problem s pamatou
« Odpověď #9 kdy: 08-12-2015, 11:11:29 »
a kdyz vyhodis Application.ProcessMessages; ?
Embarcadero MVP - Czech republic

Offline wajco

  • Nováček
  • *
  • Příspěvků: 33
  • Karma: 1
    • Verze Delphi: XE6
Re:firedac problem s pamatou
« Odpověď #10 kdy: 08-12-2015, 11:12:15 »
a kdyz je ten select porad stejny?
select * from tab where i_tab= 10 ?

stale rovnaky vysledok:(

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5109
  • Karma: 41
    • Verze Delphi: W10 + Delphi 10.4 professional
Re:firedac problem s pamatou
« Odpověď #11 kdy: 08-12-2015, 11:13:37 »
 :)  Tak potom prečo sa tak správa? Rád by som to vedel.
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline wajco

  • Nováček
  • *
  • Příspěvků: 33
  • Karma: 1
    • Verze Delphi: XE6
Re:firedac problem s pamatou
« Odpověď #12 kdy: 08-12-2015, 11:14:17 »
a kdyz vyhodis Application.ProcessMessages; ?

nepomaha

Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 2655
  • Karma: 103
    • Verze Delphi: D2007, DXE + 2 poslední
    • O Delphi v češtině
Re:firedac problem s pamatou
« Odpověď #13 kdy: 08-12-2015, 11:14:31 »
A jen pro zajímavost: kdyz das misto * nejaky konkretni sloupec?

Tohle znáš? http://delphi.cz/post/DDDebug.aspx
Embarcadero MVP - Czech republic

Offline wajco

  • Nováček
  • *
  • Příspěvků: 33
  • Karma: 1
    • Verze Delphi: XE6
Re:firedac problem s pamatou
« Odpověď #14 kdy: 08-12-2015, 11:18:00 »
A jen pro zajímavost: kdyz das misto * nejaky konkretni sloupec?

Tohle znáš? http://delphi.cz/post/DDDebug.aspx

nad jednym stlpcom stupa pamat tiez, ale samozrejme pomalsie. mrknem na ten debugger

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2837
  • Karma: 134
    • Verze Delphi: D2007, XE3, DX10
Re:firedac problem s pamatou
« Odpověď #15 kdy: 08-12-2015, 11:22:28 »
nad jednym stlpcom stupa pamat tiez, ale samozrejme pomalsie. mrknem na ten debugger
A v jakem stavu mas transakci? Nezustava ti otevrena a nesysluji se ti mak vsechna data?

My na vsech platformach a se vsemi typy RDMBS vzdycky cteme data pod explicitne nastartovanou a commitnutou read only transakci.

Offline wajco

  • Nováček
  • *
  • Příspěvků: 33
  • Karma: 1
    • Verze Delphi: XE6
Re:firedac problem s pamatou
« Odpověď #16 kdy: 08-12-2015, 11:26:11 »
nad jednym stlpcom stupa pamat tiez, ale samozrejme pomalsie. mrknem na ten debugger
A v jakem stavu mas transakci? Nezustava ti otevrena a nesysluji se ti mak vsechna data?

My na vsech platformach a se vsemi typy RDMBS vzdycky cteme data pod explicitne nastartovanou a commitnutou read only transakci.

nerobim to v transakcii

Offline hlucheucho

  • Plnoletý
  • ***
  • Příspěvků: 196
  • Karma: 2
Re:firedac problem s pamatou
« Odpověď #17 kdy: 08-12-2015, 11:28:07 »
"Sypeš to tam" aniž bys řešil odezvu DB. DB může dotaz zpracovávat delší dobu než za jakou vytvoříš a pošleš nový dotaz. Převzal bych přijatá data a pak bych poslal další dotaz. Obsluhuj události FDQuery (myslím AfterOpen). Takto jsem pracoval s MySQL, běželo to celý den bez nárůstu paměti.

Pokud používáš parametrický dotaz, SQLText stačí vytvořit jen jednou před vstupem do cyklu.

Komunikaci s DB může být vhodnější umístit do samostatného vlákna.

hu

Offline wajco

  • Nováček
  • *
  • Příspěvků: 33
  • Karma: 1
    • Verze Delphi: XE6
Re:firedac problem s pamatou
« Odpověď #18 kdy: 08-12-2015, 11:34:11 »
"Sypeš to tam" aniž bys řešil odezvu DB. DB může dotaz zpracovávat delší dobu než za jakou vytvoříš a pošleš nový dotaz. Převzal bych přijatá data a pak bych poslal další dotaz. Obsluhuj události FDQuery (myslím AfterOpen). Takto jsem pracoval s MySQL, běželo to celý den bez nárůstu paměti.

Pokud používáš parametrický dotaz, SQLText stačí vytvořit jen jednou před vstupem do cyklu.

Komunikaci s DB může být vhodnější umístit do samostatného vlákna.

hu

v BDE to ide  bez narastu pamati, to len firedac ma takyto problem

Offline hlucheucho

  • Plnoletý
  • ***
  • Příspěvků: 196
  • Karma: 2
Re:firedac problem s pamatou
« Odpověď #19 kdy: 08-12-2015, 11:39:57 »
Když posílám select, očekávám data. Kromě dotazů se tam mohou hromadit i přijatá data. Vždycky jsem zpracoval odezvu DB a neměl jsem problém s Memory Leak ani u FireDAC.

hu

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2837
  • Karma: 134
    • Verze Delphi: D2007, XE3, DX10
Re:firedac problem s pamatou
« Odpověď #20 kdy: 08-12-2015, 11:50:40 »
nerobim to v transakcii
No to neni zcela urcite pravda - komunikace s RDMBS urcite pod nejakou transakci bezi. Takze pouzivas nejakou default txn z FireDac, ktera je buhvi jak nastavena.

Osobne bych doporucoval transakce neignorovat a i kdyz je to nepohodlne, tak si je pekne explicitne ridit.

Offline wajco

  • Nováček
  • *
  • Příspěvků: 33
  • Karma: 1
    • Verze Delphi: XE6
Re:firedac problem s pamatou
« Odpověď #21 kdy: 08-12-2015, 11:57:45 »
nerobim to v transakcii
No to neni zcela urcite pravda - komunikace s RDMBS urcite pod nejakou transakci bezi. Takze pouzivas nejakou default txn z FireDac, ktera je buhvi jak nastavena.

Osobne bych doporucoval transakce neignorovat a i kdyz je to nepohodlne, tak si je pekne explicitne ridit.

tak jedine nastavenie txOptions ktore som zmenil su DisconnectAction xdRollback a Isolation xiDirtyRead




Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2837
  • Karma: 134
    • Verze Delphi: D2007, XE3, DX10
Re:firedac problem s pamatou
« Odpověď #22 kdy: 08-12-2015, 12:03:51 »
v BDE to ide  bez narastu pamati, to len firedac ma takyto problem
S BDE bych zrovna nic nesrovnaval, tak je spis divne, ze to vubec neco dela :-)

BTW, jaky je smysl dotazu, ktery nic s vytazenymi daty nedela? Normalne by za open nasledovalo neco jako
Kód: Delphi [Vybrat]
  1. Query1.Open;
  2. while not Query1.Eof do
  3.   begin
  4.      .... Query.Fields[x].AsXxxx;
  5.      Query1.Next;
  6.   end;
  7.  

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5109
  • Karma: 41
    • Verze Delphi: W10 + Delphi 10.4 professional
Re:firedac problem s pamatou
« Odpověď #23 kdy: 08-12-2015, 12:04:25 »
No, kompletný kód by mal byť takýto:
Kód: Delphi [Vybrat]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var i: Integer;
  3.   q: TFDQuery;
  4. begin
  5.   i:= 0;
  6.   Randomize;
  7.   q := TFDQuery.Create(self);
  8.   q.Connection := SomeConnection;
  9.   q.Trnasaction := SomeBasicTransaction;
  10.   q.SQL.Text := 'select * from tab where i_tab = :p';
  11.  
  12.   while True do
  13.     begin
  14.       q.Close:  // Moja skúsenosť.
  15.       q.ParamByName('p').AsInteger := Random(182064);
  16.       inc(i);
  17.       Label14.Caption := i.ToString();
  18.       Application.ProcessMessages;
  19.       q.Open();
  20.     end;
  21. end;
  22.  
Predpokladám, že to je len tak narýchlo čosi čiastočne opísané. Ako by som to robil ja ;)
Osobne ma zaujíma, že ak dáš
Kód: Delphi [Vybrat]
  1. Label14.Caption := i.ToString() + ' - ' + SomeField.AsString;
  2.  
či sa bude meniť hodnota poľa.
« Poslední změna: 08-12-2015, 12:06:01 od Stanislav Hruška »
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline wajco

  • Nováček
  • *
  • Příspěvků: 33
  • Karma: 1
    • Verze Delphi: XE6
Re:firedac problem s pamatou
« Odpověď #24 kdy: 08-12-2015, 12:06:53 »
v BDE to ide  bez narastu pamati, to len firedac ma takyto problem
S BDE bych zrovna nic nesrovnaval, tak je spis divne, ze to vubec neco dela :-)

BTW, jaky je smysl dotazu, ktery nic s vytazenymi daty nedela? Normalne by za open nasledovalo neco jako
Kód: Delphi [Vybrat]
  1. Query1.Open;
  2. while not Query1.Eof do
  3.   begin
  4.      .... Query.Fields[x].AsXxxx;
  5.      Query1.Next;
  6.   end;
  7.  
to je len ilustracny priklad

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2837
  • Karma: 134
    • Verze Delphi: D2007, XE3, DX10
Re:firedac problem s pamatou
« Odpověď #25 kdy: 08-12-2015, 12:12:24 »
to je len ilustracny priklad
To je sice vyborny, ale na zaklade ceho myslis, ze dostatnes relevantni odpoved, kdyz jsi apriory udelal rozhodnuti o tom, kde ten memory leak urcite neni  :o

Offline wajco

  • Nováček
  • *
  • Příspěvků: 33
  • Karma: 1
    • Verze Delphi: XE6
Re:firedac problem s pamatou
« Odpověď #26 kdy: 08-12-2015, 12:22:26 »
to je len ilustracny priklad
To je sice vyborny, ale na zaklade ceho myslis, ze dostatnes relevantni odpoved, kdyz jsi apriory udelal rozhodnuti o tom, kde ten memory leak urcite neni  :o

ved som skusil spustit len tento zdrojak a som videl ako mi pamat stupa, tak naco tam budem dohadzovat ostatny kod...

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2837
  • Karma: 134
    • Verze Delphi: D2007, XE3, DX10
Re:firedac problem s pamatou
« Odpověď #27 kdy: 08-12-2015, 12:28:34 »
ved som skusil spustit len tento zdrojak a som videl ako mi pamat stupa, tak naco tam budem dohadzovat ostatny kod...
No protoze ten kod ma - eufemisticky receno - spekulativni charakter a jak jsem prubezne psal, vykazuje radu vlastnosti, ktere se mi nelibi a ktere bychom nikdy nenapsali. A protoze pouzivame databaze zpusobem, jaky se predpoklada, tak jsme nikdy nehonili takovouhle ducharinu. A pod FireDac jsem pred lety portoval docela rozsahlou rodinu aplikaci z FIB+, kterou jsem ani sam nepsal. A na zadne problemy si nepamatuju.

Proto by mne zajimalo, jak se to bude chovat, kdyz se s tim pracuje radnym zpusobem.

Offline hlucheucho

  • Plnoletý
  • ***
  • Příspěvků: 196
  • Karma: 2
Re:firedac problem s pamatou
« Odpověď #28 kdy: 08-12-2015, 13:23:31 »
V obsluze události kliknutí na tlačítko bych si odpustil nekonečnou smyčku a ProcessMessage. Opakování select jde udělat i bez nich.

hu

Offline wajco

  • Nováček
  • *
  • Příspěvků: 33
  • Karma: 1
    • Verze Delphi: XE6
Re:firedac problem s pamatou
« Odpověď #29 kdy: 08-12-2015, 13:54:49 »
V obsluze události kliknutí na tlačítko bych si odpustil nekonečnou smyčku a ProcessMessage. Opakování select jde udělat i bez nich.

hu
nekonecna slucka je na znazornnie kvoli tej narastajucej pamati
process je kvoli refreshu labelu
« Poslední změna: 08-12-2015, 13:56:45 od wajco »