4

IHTMLDocument (IHTMLDocument2) を使用した後にメモリを解放する方法はありますか?

現在、EmptyWorkingSet関数を使用していますが、それは良い方法ではないと感じています

EmptyWorkingSet(GetCurrentProcess);

TWebBrowser を解放しても役に立ちません。問題は、メモリから解放されていない IHTMLDocument COM クラスにあるようです。それを解放する明確な方法はありますか?Marshal.ReleaseComObjectのようなものですが、Delphi で利用できますか?

JavaScript を実行するよりも少ないメモリ損失で再現可能ですが、それでもなお. フォームの上部に2つのボタンを配置して、次のコードを試してみると...

uses MSHTML, SHDocVw;

type
  TForm1 = class(TForm)
  private
    WebBrowser: TWebBrowser;
    HTMLDocument: IHTMLDocument2;
  end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  WebBrowser := TWebBrowser.Create(nil);
  TWinControl(WebBrowser).Parent := Self;
  WebBrowser.SetBounds(8, 39, ClientWidth-16, ClientHeight-47);
  WebBrowser.Navigate('http://maps.google.com/');
  HTMLDocument := WebBrowser.Document as IHTMLDocument2;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  WebBrowser.Free;
  HTMLDocument := nil;
end;

WebBrowser が解放されるたびにメモリが失われるのがわかります。JavaSrcipt を実行すると、300 kB をはるかに超え、約 1 MB になり、これを何度も実行するとメモリ リークが発生する可能性があります。

どうもありがとう

4

4 に答える 4

3

通常、COM クラスは、それらへのすべての参照を解放するときに解放する必要があります。通常、これは、インターフェイスへの参照を保持するすべての変数に nil を割り当てることで実行できます。

COM DLL によって使用されるメモリをすぐに解放するには、CoFreeUnusedLibrariesExを使用できます。

于 2011-05-18T22:10:12.767 に答える
0

Delphi についてはわかりませんが、C++ で IHTMLDocument を使用したことがあります。Release() メソッドを呼び出す必要があると思います。また、文字列にBSTRを使用していることもわかっているため、解放されていないメモリを探す別の場所になる可能性があります。

于 2011-05-18T22:16:09.110 に答える
0

Navigate('about:blank'); を試しましたか? 解放前?これにより、すでに一部のメモリが解放されているはずです。また、WebBrower の内部構造 (Internet Explorer とほぼ同じ内部構造) は、履歴を提供し、他の TWebBrowser (より具体的には IWebBrowser2) にキャッシュするためだけに、多くのことをメモリに保持している思います。 (近い)将来であっても、実行可能ファイルのこのセッション。

少し運が良ければ (Navigate または Navigate2 を使用している場合)、 navNoHistory、navNoWriteToCache などのフラグで呼び出すと、これを変更できます。

于 2011-05-19T17:25:03.330 に答える
0

この問題は、TWebbrowser ユーザーを長い間悩ませてきましたが、今のところ解決策はありません。TWebbrowser が使用するメモリを解放する唯一の方法は、アプリを閉じてからもう一度開くことです。

于 2015-06-11T01:33:06.890 に答える