通过delphi应用程序减少内存消耗

时间:2015-06-24 20:39:49

标签: delphi memory-leaks ihtmldocument2

我在我的一个线程系统中收到一个hd和一个TIdHttp并用IHTMLDocument2处理这个html,如下所示:

 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;

我的问题是这个代码每3秒执行一次,每次执行此代码时,内存消耗量增加1.000k,这个应用程序会消耗大量内存,并且会随着时间的推移而减慢直到它锁定,这两行使内存增加的是:

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

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

注意:我总是销毁使用FreeAndNil()创建的IHTMLDocument2组件 知道如何改进这段代码,以便停止这种内存消耗吗?

谢谢!

1 个答案:

答案 0 :(得分:4)

  

我总是销毁使用FreeAndNil()

创建的IHTMLDocument2组件

你做不到。没有IHTMLDocument2 组件。您正在创建实现IHTMLDocument2 接口的COM对象的实例,并且该接口是引用计数的。它的底层实现对象不是基于TObject(因为它不是以Delphi开头编写的)。当引用计数降为0时,接口会自动释放其底层对象。只是让变量超出范围。如果您必须手动减少引用计数,请使用nil将界面设置为FreeAndNil()

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

话虽如此,还有另一种方法可以将HTML加载到IHTMLDocument2 - 为IPersistStreamInit接口查询它,然后调用其Load()方法,该方法需要IStream作为输入。无需将docuent置于设计模式或处理窗口消息。您可以将HTML放入IStreamTStringStream,然后将其打包到TMemoryStream内,从而获得HTML TStreamAdapter