Autor Téma: firedac problem s pamatou  (Přečteno 3950 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ů: 2393
  • Karma: 103
    • Verze Delphi: D5,D2007, DXE, DXE2 + 2 poslední (Tokyo)
    • 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ů: 2611
  • Karma: 133
    • 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ů: 4548
  • Karma: 40
    • Verze Delphi: XE7 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.
Delphi XE7, FireBird
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ů: 4548
  • Karma: 40
    • Verze Delphi: XE7 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í.
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 2393
  • Karma: 103
    • Verze Delphi: D5,D2007, DXE, DXE2 + 2 poslední (Tokyo)
    • 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ů: 2393
  • Karma: 103
    • Verze Delphi: D5,D2007, DXE, DXE2 + 2 poslední (Tokyo)
    • 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ů: 4548
  • Karma: 40
    • Verze Delphi: XE7 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.
Delphi XE7, FireBird
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ů: 2393
  • Karma: 103
    • Verze Delphi: D5,D2007, DXE, DXE2 + 2 poslední (Tokyo)
    • 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ů: 2611
  • Karma: 133
    • 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ů: 2611
  • Karma: 133
    • 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ů: 2611
  • Karma: 133
    • 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ů: 4548
  • Karma: 40
    • Verze Delphi: XE7 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 »
Delphi XE7, FireBird
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ů: 2611
  • Karma: 133
    • 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ů: 2611
  • Karma: 133
    • 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 »