我在我的一个线程系统中收到一个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组件 知道如何改进这段代码,以便停止这种内存消耗吗?
谢谢!
答案 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放入IStream
或TStringStream
,然后将其打包到TMemoryStream
内,从而获得HTML TStreamAdapter
。