用delphi应用程序降低内存消耗

用delphi应用程序降低内存消耗,delphi,memory-leaks,ihtmldocument2,Delphi,Memory Leaks,Ihtmldocument2,我的单线程系统中有一个接收html的TIdHttp,并使用IHTMLDocument2处理此html,如下所示: if IDocTabela = nil then IDocTabela := CreateComObject(Class_HTMLDOcument) as IHTMLDocument2 else IDocTabela.clear; IDocTabela.designMode := 'on'; if IENovo = False then while ID

我的单线程系统中有一个接收html的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;

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

谢谢

我总是销毁使用FreeAndNil()创建的IHTMLDocument2组件

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

也就是说,还有另一种方法可以将HTML加载到
IHTMLDocument2
——查询
IPersistStreamInit
接口,然后调用其
load()
方法,该方法将
IStream
作为输入。无需将document置于设计模式,也无需处理窗口消息。通过将HTML放入
TStringStream
TMemoryStream
中,然后将其包装在
TStreamAdapter
中,可以获得HTML的
IStream

我总是销毁使用FreeAndNil()创建的IHTMLDocument2组件

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


也就是说,还有另一种方法可以将HTML加载到
IHTMLDocument2
——查询
IPersistStreamInit
接口,然后调用其
load()
方法,该方法将
IStream
作为输入。无需将document置于设计模式,也无需处理窗口消息。通过将HTML放入
TStringStream
TMemoryStream
中,然后将其包装在
TStreamAdapter

中,可以获得HTML的
IStream
,这段代码是否在线程中执行?Application.ProcessMessages不属于此处。您是否在完全调试模式下使用FastMM之类的工具验证了泄漏,或者您是否依赖任务管理器的数据?此代码位于线程内,但此过程在线程内调用,我正在任务管理器检查内存,现在我发现了一个细节,这个问题只发生在你有IE9或更高版本的时候,而IE8没有。使用win8 IE11测试时,问题会发生,win7 IE11也会发生,win7 64位、Win XP和Win 7 32位使用IE 8时,问题不会发生。IE新版本的bug?为什么调用ProcessMessages?我们可以有一个简单的MCVE吗?David,application.processmessage仅在IE版本8中是必需的,因为没有加载文档,如果没有,还有其他建议吗?这段代码是在线程中执行的吗?Application.ProcessMessages不属于此处。您是否在完全调试模式下使用FastMM之类的工具验证了泄漏,或者您是否依赖任务管理器的数据?此代码位于线程内,但此过程在线程内调用,我正在任务管理器检查内存,现在我发现了一个细节,这个问题只发生在你有IE9或更高版本的时候,而IE8没有。使用win8 IE11测试时,问题会发生,win7 IE11也会发生,win7 64位、Win XP和Win 7 32位使用IE 8时,问题不会发生。IE新版本的bug?为什么调用ProcessMessages?我们可以有一个简单的MCVE吗?David,application.processmessage仅在IE版本8中是必需的,因为文档未加载,如果不加载,还有其他建议吗?
 IDocTabela.Write(PSafeArray(System.TVarData(v).VArray));
ovTable := (IDocTabela.all.tags('TABLE') as IHTMLElementCollection).item(q, 0);
IDocTabela := CreateComObject(Class_HTMLDOcument) as IHTMLDocument2
...
IDocTabela := nil;