Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2010-01

Memory leaks when I read an XML file

6 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Pierre Delore

Hi,

I'm finishing to develop an application. Everything works fine. Yesterday I made some tests and I noticed that I have a huge memory leak when I try to load new data.

I load 6000 lines of data that I transfer in TFPObjectList. I first thought that the problem came from the list. I removed the list code and the problem doesn't disappear. So, for me, the problem come from the XML reading procedure. I try to search in the wiki and I didn't found thing that help me. I sure that the method I use to read the XML is not right one.

Somebody can help me to correct my code?

The method without TFPObjectList code is below. Before reading the file the program use 16Mo of memory. After the execution of the 'LoadCGX' procedure the program use 204Mo :( .

-------------------------------------------------------------------------------------------------------------------
procedure TCGData.LoadCGX(s:String);
var
  xdoc: TXMLDocument;                         // variable to document
  RootNode,
  node, node1, TrackpointNode : TDOMNode;    // variable to nodes
  i, j, err : Integer;
  tmpCourseName : string;
  tmpDescription : string;
  tmps, tmps1 : string;
  tmpTotalDistance,td : Double;
  tmpVersion : String;
  tmpTotalTimeSecond : integer;
  ts : String;
Begin
  DateSeparator:='/';
  ShortDateFormat:='d/m/y';
  //-- Open the XML file --
  ReadXMLFile(xDoc, s);
  //-- Search the <CourseGenerator> node --
  RootNode := xDoc.FindNode('CourseGenerator');
  if RootNode=NIL then exit; //Not found exit
  For i:=0 to (RootNode.ChildNodes.Count - 1) do begin
    Node:=RootNode.ChildNodes.Item[i];
    tmps:=Node.NodeName;
    if tmps='Version' then begin
      //-- <Version> node --
      tmpVersion:= Node.TextContent;
      //Todo: test!
    end
    else if tmps='TotalDistance' then begin
      //-- <TotalDistance> node --
      Val(Node.TextContent,tmpTotalDistance,err);
      if err0 then exit;
    end
    else if tmps='TotalTimeSecond' then begin
      //-- <TotalTimeSecond> node --
      Val(Node.TextContent,tmpTotalTimeSecond,err);
      if err0 then exit;
    end
    else if tmps='CourseName' then begin
      //-- <CourseName> node --
      tmpCourseName:= Node.TextContent;
    end
    else if tmps='Description' then begin
      //-- <Description> node --
      tmpDescription:= Node.TextContent;
    end
    else if tmps='Trackpoint' then begin
      //-- <Trackpoint> node --
      TrackpointNode := Node;
      //-- Scan level "trackpoint" --
      for j := 0 to (TrackpointNode.ChildNodes.Count - 1) do begin
        Node1:=TrackpointNode.ChildNodes.Item[j];
        tmps1:=Node1.NodeName;
        if tmps1 = 'LatitudeDegrees' then begin
          //<LatitudeDegrees>123.456</LatitudeDegrees>
          val(Node1.TextContent,td,err);
          if err0 then begin
            td:=0;
                //Error
          end;
        end
        else if tmps1 = 'LongitudeDegrees' then begin
          //<LongitudeDegrees>123.456</LongitudeDegrees>
          val(Node1.TextContent,td,err);
          if err0 then begin
            td:=0;
                //Error
          end;
        end
        else if tmps1 = 'AltitudeMeters' then begin
          //<AltitudeMeters>123.456</AltitudeMeters>
          val(Node1.TextContent,td,err);
          if err0 then begin
            td:=0;
                //Error
          end;
        end;
      end; //For j
      //-- Store data --
      //List.Add(TmpData);
    end;
  end; //For i
  RootNode.free;
  xDoc.Free;
End;
-----------------------------------------------------------------------------------------------------

Thanks for your help.

Regards,

Reply by email

Sergei Gorelkin
to Pierre Delore
Pierre Delore wrote
... I try to search in the wiki and I didn't found thing that help me.

Since you did not specify your compiler version, I guess it's something pre-2.4.0. See this link:
http://wiki.freepascal.org/User_Changes_2.4.0#dom_unit:_memory_management_for_node_lists

Either upgrade to 2.4.0, or add a matching call of Free for each call of ChildNodes. The best solution, however, is to change the code to use FirstChild/NextSibling properties instead of ChildNodes, because FirstChild/NextSibling are faster and don't create any intermediate objects.

Regards,
Sergei

Reply by email

Pierre Delore
to Sergei Gorelkin

Thanks Sergei for your answer.

I Forgot to indicate that I use the last stable version of lazarus (0.9.28.2).

I will try to modify my code to use FirstChild/NextSibling.

Regards,

Pierre Delore http://datalinkwristapps.free.fr http://dpsite.free.fr ----- "Sergei Gorelkin" a ?crit : > Pierre Delore wrote: > > ... > > I try to search in the wiki and I didn't found thing that help me. > > > Since you did not specify your compiler version, I guess it's something pre-2.4.0. > See this link: > http://wiki.freepascal.org/User_Changes_2.4.0#dom_unit:_memory_management_for_node_lists > > Either upgrade to 2.4.0, or add a matching call of Free for each call of ChildNodes. > The best solution, however, is to change the code to use FirstChild/NextSibling properties > instead of ChildNodes, because FirstChild/NextSibling are faster and don't create any intermediate > objects. > > Regards, > Sergei > > -- > _______________________________________________ > Lazarus mailing list > > http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20100110/bc9b8138/attachment-0001.html>

Reply by email

Pierre Delore
to Pierre Delore

FirstChild/NextSibling fix my problem. Thanks.

Regards,

Pierre Delore http://datalinkwristapps.free.fr http://dpsite.free.fr ----- "Pierre Delore" a ?crit : > > Thanks Sergei for your answer. > > I Forgot to indicate that I use the last stable version of lazarus (0.9.28.2). > > I will try to modify my code to use FirstChild/NextSibling. > > Regards, > > -- > Pierre Delore > > http://datalinkwristapps.free.fr > http://dpsite.free.fr > > ----- "Sergei Gorelkin" a ?crit : > > Pierre Delore wrote: > > > ... > > > I try to search in the wiki and I didn't found thing that help me. > > > > > Since you did not specify your compiler version, I guess it's something pre-2.4.0. > > See this link: > > http://wiki.freepascal.org/User_Changes_2.4.0#dom_unit:_memory_management_for_node_lists > > > > Either upgrade to 2.4.0, or add a matching call of Free for each call of ChildNodes. > > The best solution, however, is to change the code to use FirstChild/NextSibling properties > > instead of ChildNodes, because FirstChild/NextSibling are faster and don't create any intermediate > > objects. > > > > Regards, > > Sergei > > > > -- > > _______________________________________________ > > Lazarus mailing list > > > > http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20100111/a5289d5a/attachment.html>

Reply by email

Unknown author
to Pierre Delore: I'm finishing to develop an application. Everything works fine. Yesterday I made some…

Besides what you corrected, the various 'exit' statement in your code will leave an xdoc unfreed.

Pierre Delore wrote
Hi, I'm finishing to develop an application. Everything works fine.

Yesterday I made some tests and I noticed that I have a huge memory leak when I try to load new data.

I load 6000 lines of data that I transfer in TFPObjectList. I first

thought that the problem came from the list. I removed the list code and the problem doesn't disappear. So, for me, the problem come from the XML reading procedure. I try to search in the wiki and I didn't found thing that help me. I sure that the method I use to read the XML is not right one.

Show quoted text 5 lines
Somebody can help me to correct my code? The method without TFPObjectList code is below. Before reading the file

the program use 16Mo of memory. After the execution of the 'LoadCGX' procedure the program use 204Mo :( .

>

-------------------------------------------------------------------------------------------------------------------

Show quoted text 100 lines
procedure TCGData.LoadCGX(s:String); var xdoc: TXMLDocument; // variable to document RootNode, node, node1, TrackpointNode : TDOMNode; // variable to nodes i, j, err : Integer; tmpCourseName : string; tmpDescription : string; tmps, tmps1 : string; tmpTotalDistance,td : Double; tmpVersion : String; tmpTotalTimeSecond : integer; ts : String; Begin DateSeparator:='/'; ShortDateFormat:='d/m/y'; //-- Open the XML file -- ReadXMLFile(xDoc, s); //-- Search the <CourseGenerator> node -- RootNode := xDoc.FindNode('CourseGenerator'); if RootNode=NIL then exit; //Not found exit For i:=0 to (RootNode.ChildNodes.Count - 1) do begin Node:=RootNode.ChildNodes.Item[i]; tmps:=Node.NodeName; if tmps='Version' then begin //-- <Version> node -- tmpVersion:= Node.TextContent; //Todo: test! end else if tmps='TotalDistance' then begin //-- <TotalDistance> node -- Val(Node.TextContent,tmpTotalDistance,err); if err0 then exit; end else if tmps='TotalTimeSecond' then begin //-- <TotalTimeSecond> node -- Val(Node.TextContent,tmpTotalTimeSecond,err); if err0 then exit; end else if tmps='CourseName' then begin //-- <CourseName> node -- tmpCourseName:= Node.TextContent; end else if tmps='Description' then begin //-- <Description> node -- tmpDescription:= Node.TextContent; end else if tmps='Trackpoint' then begin //-- <Trackpoint> node -- TrackpointNode := Node; //-- Scan level "trackpoint" -- for j := 0 to (TrackpointNode.ChildNodes.Count - 1) do begin Node1:=TrackpointNode.ChildNodes.Item[j]; tmps1:=Node1.NodeName; if tmps1 = 'LatitudeDegrees' then begin //<LatitudeDegrees>123.456</LatitudeDegrees> val(Node1.TextContent,td,err); if err0 then begin td:=0; //Error end; end else if tmps1 = 'LongitudeDegrees' then begin //<LongitudeDegrees>123.456</LongitudeDegrees> val(Node1.TextContent,td,err); if err0 then begin td:=0; //Error end; end else if tmps1 = 'AltitudeMeters' then begin //<AltitudeMeters>123.456</AltitudeMeters> val(Node1.TextContent,td,err); if err0 then begin td:=0; //Error end; end; end; //For j //-- Store data -- //List.Add(TmpData); end; end; //For i RootNode.free; xDoc.Free; End; >

-----------------------------------------------------------------------------------------------------

Show quoted text 6 lines
Thanks for your help. Regards,
Yves Tennevin / esby <dot> free.fr http://esby.free.fr/contact.html

Reply by email

Pierre Delore
to Unknown author

Hi Yves,

Thanks for your remark. I will modify the code.

Regards,

Pierre Delore http://datalinkwristapps.free.fr http://dpsite.free.fr ----- a ?crit : > Besides what you corrected, the various 'exit' statement in your code > will leave an xdoc unfreed. > > Pierre Delore wrote: > > Hi, > > > > I'm finishing to develop an application. Everything works fine. > Yesterday I made some tests and I noticed that I have a huge memory leak > when I try to load new data. > > > > I load 6000 lines of data that I transfer in TFPObjectList. I first > thought that the problem came from the list. I removed the list code and > the problem doesn't disappear. So, for me, the problem come from the XML > reading procedure. I try to search in the wiki and I didn't found thing > that help me. I sure that the method I use to read the XML is not right > one. > > > > Somebody can help me to correct my code? > > > > > > The method without TFPObjectList code is below. Before reading the file > the program use 16Mo of memory. After the execution of the 'LoadCGX' > procedure the program use 204Mo :( . > > > > > >> > ------------------------------------------------------------------------------------------------------------------- > > procedure TCGData.LoadCGX(s:String); > > var > > xdoc: TXMLDocument; // variable to document > > RootNode, > > node, node1, TrackpointNode : TDOMNode; // variable to nodes > > i, j, err : Integer; > > tmpCourseName : string; > > tmpDescription : string; > > tmps, tmps1 : string; > > tmpTotalDistance,td : Double; > > tmpVersion : String; > > tmpTotalTimeSecond : integer; > > ts : String; > > Begin > > > > DateSeparator:='/'; > > ShortDateFormat:='d/m/y'; > > > > //-- Open the XML file -- > > ReadXMLFile(xDoc, s); > > > > > > //-- Search the <CourseGenerator> node -- > > RootNode := xDoc.FindNode('CourseGenerator'); > > > > if RootNode=NIL then exit; //Not found exit > > > > For i:=0 to (RootNode.ChildNodes.Count - 1) do begin > > Node:=RootNode.ChildNodes.Item[i]; > > tmps:=Node.NodeName; > > > > if tmps='Version' then begin > > //-- <Version> node -- > > tmpVersion:= Node.TextContent; > > //Todo: test! > > end > > else if tmps='TotalDistance' then begin > > //-- <TotalDistance> node -- > > Val(Node.TextContent,tmpTotalDistance,err); > > if err0 then exit; > > end > > else if tmps='TotalTimeSecond' then begin > > //-- <TotalTimeSecond> node -- > > Val(Node.TextContent,tmpTotalTimeSecond,err); > > if err0 then exit; > > end > > else if tmps='CourseName' then begin > > //-- <CourseName> node -- > > tmpCourseName:= Node.TextContent; > > end > > else if tmps='Description' then begin > > //-- <Description> node -- > > tmpDescription:= Node.TextContent; > > end > > > > else if tmps='Trackpoint' then begin > > //-- <Trackpoint> node -- > > TrackpointNode := Node; > > > > //-- Scan level "trackpoint" -- > > for j := 0 to (TrackpointNode.ChildNodes.Count - 1) do begin > > Node1:=TrackpointNode.ChildNodes.Item[j]; > > tmps1:=Node1.NodeName; > > > > if tmps1 = 'LatitudeDegrees' then begin > > //<LatitudeDegrees>123.456</LatitudeDegrees> > > val(Node1.TextContent,td,err); > > if err0 then begin > > td:=0; > > //Error > > end; > > end > > else if tmps1 = 'LongitudeDegrees' then begin > > //<LongitudeDegrees>123.456</LongitudeDegrees> > > val(Node1.TextContent,td,err); > > if err0 then begin > > td:=0; > > //Error > > end; > > end > > else if tmps1 = 'AltitudeMeters' then begin > > //<AltitudeMeters>123.456</AltitudeMeters> > > val(Node1.TextContent,td,err); > > if err0 then begin > > td:=0; > > //Error > > end; > > end; > > end; //For j > > //-- Store data -- > > //List.Add(TmpData); > > end; > > end; //For i > > > > > > RootNode.free; > > xDoc.Free; > > > > End; > >> > ----------------------------------------------------------------------------------------------------- > > > > > > Thanks for your help. > > > > Regards, > > > > > -- > Yves Tennevin / esby <dot> free.fr > > http://esby.free.fr/contact.html > > > -- > _______________________________________________ > Lazarus mailing list > > http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20100111/e8806e56/attachment.html>

Reply by email