1

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 イベントを示していたので、これはあまり驚くことではありません。

4

2 に答える 2

0

理由は完全にはわかりませんが、反復変数のコピーを作成すると修正されました。私が知る限り、LinqToSql はどういうわけか各ドキュメント内に DocumentSubmission のコピーを作成していました。

foreach (Document doc in ImportDocs) {
    // make copy of doc that lives inside loop scope
    Document copydoc = new Document() {
        field1 = doc.field1,
        field2 = doc.field2,
        // complete copy
    };

    using (var dc = new DocumentClassesDataContext(connection)) {
        byte[] contents = File.ReadAllBytes(copydoc.FileName);

        DocumentSubmission submission = new DocumentSubmission() {
            Content = contents,
            // other fields
        };

        dc.DocumentSubmissions.InsertOnSubmit(submission);  // (A)
        dc.SubmitChanges();                                 // (B)
    }
}
于 2009-11-20T16:25:22.277 に答える
0

どのオペレーティング システムでこれを実行していますか? 問題は Linq2Sql に関連しているのではなく、オペレーティング システムが大規模なメモリ割り当てを管理する方法に関連している可能性があります。たとえば、Windows Server 2008 は、XP よりもメモリ内の大きなオブジェクトの管理に優れています。大きなファイルを操作するコードが XP ではリークしていたが、Win 2008 サーバーでは正常に動作していたという例がありました。

HTH

于 2009-11-20T00:01:58.550 に答える