これは、.NET Webbrowser コントロールに関する広く知られている古い問題です。
概要: .NET Web ブラウザー コントロールを使用してページに移動すると、解放されないメモリの使用量が増加します。
メモリ リークを再現します。フォームに WebBrowser コントロールを追加します。これを使用して、任意のページに移動します。about:blank は機能します。使用量が 100 MB 以上になるまで Google 画像でスクロールし、その後他の場所を参照して、メモリがほとんど解放されていないことに気付くと、より劇的なデモンストレーションになります。
アプリケーションに対する現在の要件には、長時間実行し、制限された IE7 ブラウザー ウィンドウを表示することが含まれます。フック、BHO、およびグループ ポリシーの不適切な設定で IE7 自体を実行することも望ましくありませんが、現時点ではそれが代替策のように見えます。ブラウザーを Windows フォーム アプリケーションに埋め込むことは可能です。別のブラウザー ベースを使用することは、私にとっては利用可能なオプションではありません。IE7 が必要です。
この既知のメモリ リークに関連する以前のスレッドと記事:
- http://www.vbforums.com/showthread.php?t=644658
- IE WebBrowser コントロールのメモリ リークを修正するにはどうすればよいでしょうか?
- 複数のウィンドウで WPF WebBrowser コントロールを使用するとメモリ リークが発生する
- http://social.msdn.microsoft.com/Forums/en-US/ieextensiondevelopment/thread/88c21427-e765-46e8-833d-6021ef79e0c8/
- http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/8a2efea4-5e75-4e3d-856f-b09a4e215ede
- http://dotnetforum.net/topic/17400-appdomain-webbrowser-memory-leak/
よく提案されるが機能しない修正方法:
- 別のページに移動しても問題ありません。about:blank がリークを引き起こします。ページに JavaScript やその他の追加テクノロジは必要ありません。
- Internet Explorer の異なるバージョンを使用することは問題ではありません。7、8、9 はすべて同じ症状を示し、私が聞いた限りでは、すべてのバージョンでコントロールに同じメモリ リークが発生します。
- コントロールの Dispose() は役に立ちません。
- ガベージ コレクションは役に立ちません。(実際、私が行った調査では、リークは Webbrowswer コントロールがラップするアンマネージ COM コードにあることが示されています。)
- プロセスの使用可能なメモリを最小化して -1、-1(SetProcessWorkingSetSize() または同様の値)に設定すると、物理メモリの使用量のみが削減され、仮想メモリには影響しません。
- WebBrowser.Stop() を呼び出すことは解決策ではなく、リークをわずかに最小限に抑えるだけで、静的 Web ページ以外の機能を使用する機能が壊れます。
- 別のドキュメントに移動する前に、ドキュメントが完全に読み込まれるまで強制的に待機させることも役に立ちません。
- コントロールを別の appDomain にロードしても問題は解決しません。(私は自分でこれを試したことはありませんが、調査によると、他の人はこの方法で成功していないようです。)
- csexwb2 などの別のラッパーを使用しても同じ問題が発生するため、役に立ちません。
- 一時インターネット ファイルのキャッシュをクリアしても何も変わりません。問題はディスク上ではなく、アクティブ メモリにあります。
アプリケーション全体を閉じて再起動すると、メモリはクリアされます。
それが問題を確実に解決するのであれば、COM または Windows API で直接独自のブラウザ コントロールを記述するつもりです。もちろん、より簡単な修正を希望します。ブラウザのサポート機能に関して車輪の再発明をしたくないので、下位レベルに降りて作業するのは避けたいです。ましてや、IE7 の機能や非標準の動作を、独自のブラウザで複製するのはなおさらです。
ヘルプ?
ベストアンサー1
このリークは管理されていないメモリのリークのようです。そのため、プロセス内で何をしてもそのメモリを再利用することはできません。投稿から、リークを回避しようとかなり努力したが、成功しなかったことがわかります。
可能であれば、別のアプローチをお勧めします。Webブラウザコントロールを使用する別のアプリケーションを作成し、アプリケーションから起動します。説明されている方法を使用してください。ここ新しく作成したアプリケーションを既存のアプリケーション内に埋め込みます。WCF または .NET リモート処理を使用してそのアプリケーションと通信します。メモリを大量に消費しないように、子プロセスを定期的に再起動します。
もちろん、これは非常に複雑なソリューションであり、再起動のプロセスは見た目が悪くなる可能性があります。ユーザーが別のページに移動するたびに、ブラウザ アプリケーション全体を再起動する必要があるかもしれません。