0

Im refreshing DBXJSON TJSONArray in timer loop , but i detect that my algorithm leak memory im supect that im not using in the right way the library. whats its wrong here?

I need to reload the Array COMANDASTOT , this array its used by others threads who use them to replace data and get data.

The Idea is UPDATE the infomation stored in TJSONArray, but when i Update the Array this start leaking

Thanks!

uses ....

var
 COMANDASTOT:TJSONARRAY;
 ROOTCOMANDAS:TJSONOBJECT;


procedure tmain.FormCreate(Sender: TObject);

 RespContent: TMemoryStream;
 s, id, strd, et: String;

 LValues, pedidos: TJSONArray;
 LJson, Comand: TJSONOBJECT;

 LValue, pedido: TJsonValue;

 F: TextFile;

 RC: TRESTClient;
 RR: TRESTResponse;
 RQ: TRESTRequest;
begin


try
        // USING TRESTCLIENT VCL TO GET JSON OBJECT FROM CLOUDSERVER

         RC := TRESTClient.Create('https://cloudorders.example.com/getorders?id=3456);

          RQ := TRESTRequest.Create(RC);

          RQ.Execute;

          RQ.Response.RootElement:='';

     ROOTCOMANDAS := RQ.Response.JSONValue as TJSONOBJECT;

    if not DirectoryExists('htd\resto\orders') then
      CreateDir('htd\resto\orders');



    if DirectoryExists('htd\resto\orders') then
    begin

        // SAVING JSON DATA TO DISK 

       assignfile(f,'htd\resto\orders\process');
       rewrite(f);
       writeln(f,RQ.Response.content);
       closefile(f);                     }

    end;

    Comand := ROOTCOMANDAS.Get('data').JSONValue as TJSONOBJECT;

    ETAG := Comand.GetValue('et').Value;

    COMANDASTOT := Comand.Get('d').JSONValue as TJSONArray; // <<- ARRAY LOADED FIRST TIME

    COMANDASTOT.Owned:=false;



 RQ.Free;
 RC.Free;

except
  on E: Exception do
  begin


    Memo1.Lines.Add(ahora + 'Error Loading JsonArray: ' + E.Message);



   end;
   end;
 end;

 Procedure TMain.Timer1Timer(Sender: TObject);
 begin

     // Called each 30 sec. Other process change the file

        If DataChange then
             ReadFromDiskJSON;


  end;


procedure tmain.ReadFromDiskJSON;
 Var
 fs:tfilestream;
 orders,MD5s:string;
 COM,ljson:tjsonobject;
 begin
  try

   while NOT FileCanBeOpened('htd\resto\orders\process') do
   begin
     sleep(100);
   end;

   fs := TFileStream.Create('htd\resto\orders\process',fmOpenRead + fmShareDenyWrite);

   orders := ReadStringFromStream(fs);

   COM := TJSONOBJECT.ParseJSONValue(orders) as TJSONOBJECT;

    LJson := COM.Get('data').JSONValue as TJSONOBJECT;


    /// THIS SENTENCE LEAK MEMORY 
    ///  Why??????

    COMANDASTOT:= LJSON.Get('d').JSONValue as TJSONArray   ; // <<<-THIS LEAK MEMORY!!

    COMANDASTOT.Owned:=false;

    com.Free;
     fs.Free;

    except on e: Exception do
   begin
     memo1.Lines.Add(SNow+' Error ReadFromDiskJSON'+e.Message);
     fs.Free;
    end;
    end;

   end;
JavierDonosoV
  • 33
  • 2
  • 6
  • 2
    COMANDASTOT.Owned:=false; that is creating the leak, you should Free that object yourself when you are done with it. – Dalija Prasnikar Jan 08 '15 at 21:41
  • yes you right! , but the idea its that , maintain Comandastot Loaded but with New and Fresh data, which is saved in file by others processes, the issue is that Comandastot Leak and leak.. maybe when you call again the same code the array get another memory address with the new parsed JSON , keeping the old memory used by the old tjsonarray... there is a way to refresh that array??? – JavierDonosoV Jan 08 '15 at 22:29
  • 2
    That's not your actual code, because it's not even close to being able to compile. If you have a question about a problem with your code, *post your actual code*. Making it up as you go along often hides the problem or actually creates a new one. (Ignoring the missing content of the `uses` clause, the next three lines were enough to show it was not actual code.) – Ken White Jan 08 '15 at 23:14
  • There is a way to quickly fix it by calling `COMANDASTOT.Free` just before you assign new value to that variable. Since`COMANDASTOT` is global variable it will be initialized to `nil` and it is safe to call `Free` on `nil` variable and that code will run fine on first run too. – Dalija Prasnikar Jan 09 '15 at 09:48
  • Besides quick fix, you should really avoid using global variables because that is road to hell. – Dalija Prasnikar Jan 09 '15 at 09:51
  • I forgot to add that you should also call `COMANDASTOT.Free` in your unit finalization section. – Dalija Prasnikar Jan 09 '15 at 09:54
  • I "resolve" the issue changing my aproach ... using disk instead memory ... its clear that use DBXJson its hard.. im going to test iSuperObject... – JavierDonosoV Jan 15 '15 at 14:27

0 Answers0