C# アプリケーションの「メモリ リーク」の原因を突き止めようとしています。image
このアプリケーションは、SQL Server の列の種類を使用して、多数の潜在的に大きなファイルをデータベースのレコードにコピーします。LinqToSql
すべてのデータベース アクセスに および関連オブジェクトを使用しています。
メイン ループは、ファイルと挿入のリストを反復処理します。多くのボイラープレートとエラー処理を削除すると、次のようになります。
foreach (Document doc in ImportDocs) {
using (var dc = new DocumentClassesDataContext(connection)) {
byte[] contents = File.ReadAllBytes(doc.FileName);
DocumentSubmission submission = new DocumentSubmission() {
Content = contents,
// other fields
};
dc.DocumentSubmissions.InsertOnSubmit(submission); // (A)
dc.SubmitChanges(); // (B)
}
}
入力全体に対してこのプログラムを実行すると、最終的にOutOfMemoryException
. CLR Profiler は、ヒープの 99% がbyte[]
、ファイルのサイズに対応する大きなオブジェクトで構成されていることを示しています。
行 A と行 B の両方にコメントすると、このリークはなくなります。A 行だけコメントを外すと、リークが再発します。dc
ループの繰り返しごとに破棄されるため 、これがどのように可能かわかりません。
誰もこれに遭遇したことがありますか?ストアド プロシージャを直接呼び出すか、挿入を行うことでこのリークを回避できると思いますが、他のことを試す前にこれを理解したいと思います。何が起こっている?
アップデート
行 (B) の後に含めGC.Collect();
ても、どのような場合にも大きな変化はないようです。CLR プロファイラーは、明示的にそれらを誘発することなく、かなりの数の GC イベントを示していたので、これはあまり驚くことではありません。