Reduce memory consumption by delphi application

626 views Asked by At

I have in my one thread system that receives an html a TIdHttp and treats this html with IHTMLDocument2 as below:

 if IDocTabela = nil then
    IDocTabela := CreateComObject(Class_HTMLDOcument) as IHTMLDocument2
 else
    IDocTabela.clear;

 IDocTabela.designMode := 'on';
 if IENovo = False then
  while IDocTabela.readyState <> 'complete' do
     Application.ProcessMessages;

 v := VarArrayCreate([0, 0], VarVariant);
 v[0] := xHtml;
 IDocTabela.Write(PSafeArray(System.TVarData(v).VArray));
 IDocTabela.designMode := 'off';
 if IENovo = False then
  while IDocTabela.readyState <> 'complete' do
     Application.ProcessMessages;

 for q := 0 to (IDocTabela.all.tags('TABLE') as IHTMLElementCollection).Length -1 do
    begin
      ovTable := (IDocTabela.all.tags('TABLE') as IHTMLElementCollection).item(q, 0);

      for i := 0 to (ovTable.Rows.Length - 1) do
        begin
          for j := 0 to (ovTable.Rows.Item(i).Cells.Length - 1) do
            begin
              sTemp := TrimRight(TrimLeft(ovTable.Rows.Item(I).Cells.Item(J).InnerText));
              if (sTemp = 'Item') = true then
                 begin
                  bSai := True;
                  Break;
                 end;
            end;
            if bSai = True then
              Break;
        end;
      if bSai = True then
        Break;
    end;

My problem is that this code is executed every 3 seconds, and every time this code executes, the memory consumption increases in 1.000k with this application will consume a lot of memory and slowing down over time until it locks, the two lines that make the memory increases are:

 IDocTabela.Write(PSafeArray(System.TVarData(v).VArray));

and

ovTable := (IDocTabela.all.tags('TABLE') as IHTMLElementCollection).item(q, 0);

Note: I always destroy the IHTMLDocument2 component created with FreeAndNil() Any idea how to improve this code, so that this memory consumption stop occur?

Thanks!

1

There are 1 answers

0
Remy Lebeau On

I always destroy the IHTMLDocument2 component created with FreeAndNil()

You cannot do that. There is no IHTMLDocument2 component. You are creating an instance of a COM object that implements the IHTMLDocument2 interface, and that interface is reference-counted. Its underlying implementation object is not based on TObject (since it is not written in Delphi to begin with). An interface frees its underlying object automatically when its reference count falls to 0. Just let the variable go out of scope. If you must decrement the reference count manually, set the interface to nil instead using FreeAndNil():

IDocTabela := CreateComObject(Class_HTMLDOcument) as IHTMLDocument2
...
IDocTabela := nil;

That being said, there is another way to load HTML into an IHTMLDocument2 - query it for the IPersistStreamInit interface and then call its Load() method, which takes an IStream as input. No need for putting the docuent into design mode, or processing window messages. You can get an IStream for your HTML by putting your HTML into a TStringStream or TMemoryStream and then wrap it inside a TStreamAdapter.