私は最近、仕事用に保守しているアプリケーションでメモリ リークを発見しました。なぜコードがリークを引き起こすのか混乱しています。関連するコードを (わずかに変更して) 取り出し、以下に示します。
このアプリケーションでは、特定の XML ドキュメントを 1 つ以上の使用可能なスキーマ ファイルに対して検証できます。各スキーマ ファイルは、時間の経過とともに変更された XML ドキュメントの異なるバージョンに対応しています。XML ドキュメントが少なくとも 1 つのスキーマに対して検証されることのみを考慮します。各スキーマは、XML ドキュメントの内容を完全に記述します (ネストされたスキーマ ファイルではありません)。
ANTS メモリ プロファイラによると、スキーマ セットがクリアされた後でも、XmlDocument オブジェクトが以前のスキーマへの参照を保持しているようです。Validate() の呼び出しをコメントアウトし、他のすべてを同じままにすると、リークが停止します。
アプリケーションの初期化時に一度スキーマをロードし、妥当性が確認できるスキーマ ファイルが見つかるまで、XML ドキュメントに関連付けられているスキーマ ファイルを交換することで、アプリケーションのリークを修正しました。
以下のコードではメモリ リークが発生しますが、その理由はわかりません。
class Program
{
private static XmlDocument xmlDocument_ = new XmlDocument();
static void Main(string[] args)
{
using (StreamReader reader = new StreamReader("contents.xml"))
{
xmlDocument_.LoadXml(reader.ReadToEnd());
}
XmlReaderSettings xmlReaderSettings = new XmlReaderSettings();
xmlReaderSettings.CloseInput = true;
while (true)
{
xmlDocument_.Schemas = new XmlSchemaSet();
XmlReader xmlReader = XmlReader.Create("schema.xsd", xmlReaderSettings);
xmlDocument_.Schemas.Add(XmlSchema.Read(xmlReader, null));
xmlReader.Close();
xmlDocument_.Validate(null);
}
}
}