WebBrowser コントロールで MSHTML を使用しているのは、テキスト ノードなど、WebBrowser ではアクセスできないものにアクセスできるためです。ReleaseComObject
ここや Web で、参照するすべての COM オブジェクトを呼び出さなければならないという投稿をいくつか見ました。だから、私がこれをするとしましょう:
var doc = myBrowser.Document.DomDocument as IHTMLDocument2;
リリースする必要がありdoc
ますか? body
このコードでの方法:
var body = (myBrowser.Document.DomDocument as IHTMLDocument2).body;
これらのオブジェクトは、それらへの参照がなくなるとすぐに解放する RCW によってラップされていませんか? そうでない場合は、ガベージコレクターが作動するとすぐにそれらを解放する(Disposeを使用する代わりに)ファイナライザーを使用して、それぞれのラッパーを作成することをお勧めします(手動で心配する必要がないように)それらを処分する)?
問題は、私のアプリケーションにメモリ リークがあり、これに関連していると思われることです。Microsoft.CSharp.RuntimeBinder.Semantics.LocalVariableSymbol
ANTS メモリ プロファイラーによると、第 2 世代でメモリを使用するオブジェクトのトップ リストにある一連のオブジェクトへの参照を保持している関数の 1 つ (MSHTML オブジェクトを使用する他の多くの関数の中でも) は次のとおりです。
internal static string GetAttribute(this IHTMLDOMNode element, string name)
{
var attribute = element.IsHTMLElement() ? ((IHTMLElement)element).getAttribute(name) : null;
if (attribute != null) return attribute.ToString();
return "";
}
attribute
単なる文字列であるため、ここで何が問題なのかわかりません。
ANTS プロファイラーのインスタンス保持グラフに表示される別の関数を次に示します (一連の を追加しましたFinalReleaseComObject
が、まだ表示されています)。
private void InjectFunction(IHTMLDocument2 document)
{
if (null == Document) throw new Exception("Cannot access current document's HTML or document is not an HTML.");
try
{
IHTMLDocument3 doc3 = document as IHTMLDocument3;
IHTMLElementCollection collection = doc3.getElementsByTagName("head");
IHTMLDOMNode head = collection.item(0);
IHTMLElement scriptElement = document.createElement("script");
IHTMLScriptElement script = (IHTMLScriptElement)scriptElement;
IHTMLDOMNode scriptNode = (IHTMLDOMNode)scriptElement;
script.text = CurrentFuncs;
head.AppendChild(scriptNode);
if (Document.InvokeScript(CurrentTestFuncName) == null) throw new Exception("Cannot inject Javascript code right now.");
Marshal.FinalReleaseComObject(scriptNode);
Marshal.FinalReleaseComObject(script);
Marshal.FinalReleaseComObject(scriptElement);
Marshal.FinalReleaseComObject(head);
Marshal.FinalReleaseComObject(collection);
//Marshal.FinalReleaseComObject(doc3);
}
catch (Exception ex)
{
throw ex;
}
}
を追加しましたReleaseComObject
が、関数はまだ何かへの参照を保持しているようです。これが私の関数が今どのように見えるかです:
private void InjectFunction(IHTMLDocument2 document)
{
if (null == Document) throw new Exception("Cannot access current document's HTML or document is not an HTML.");
try
{
IHTMLDocument3 doc3 = document as IHTMLDocument3;
IHTMLElementCollection collection = doc3.getElementsByTagName("head");
IHTMLDOMNode head = collection.item(0);
IHTMLElement scriptElement = document.createElement("script");
IHTMLScriptElement script = (IHTMLScriptElement)scriptElement;
IHTMLDOMNode scriptNode = (IHTMLDOMNode)scriptElement;
script.text = CurrentFuncs;
head.AppendChild(scriptNode);
if (Document.InvokeScript(CurrentTestFuncName) == null) throw new Exception("Cannot inject Javascript code right now.");
Marshal.FinalReleaseComObject(scriptNode);
Marshal.FinalReleaseComObject(script);
Marshal.FinalReleaseComObject(scriptElement);
Marshal.FinalReleaseComObject(head);
Marshal.FinalReleaseComObject(collection);
Marshal.ReleaseComObject(doc3);
}
catch (Exception ex)
{
MessageBox.Show("Couldn't release!");
throw ex;
}
}
ラインがヒットすることはありませんので、MessageBox.Show("Couldn't release!");
すべてが適切にリリースされていると思います。ANTSが示すものは次のとおりです。
そのサイトコンテナが何であるかわかりません。