Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# LinqToSql InsertOnSubmit内存泄漏?_C#_Linq To Sql_Memory Leaks_Out Of Memory - Fatal编程技术网

C# LinqToSql InsertOnSubmit内存泄漏?

C# LinqToSql InsertOnSubmit内存泄漏?,c#,linq-to-sql,memory-leaks,out-of-memory,C#,Linq To Sql,Memory Leaks,Out Of Memory,我正试图找出C#应用程序中“内存泄漏”的根源。此应用程序使用SQL Server中的image列类型将大量可能较大的文件复制到数据库中的记录中。我正在使用LinqToSql和关联对象进行所有数据库访问 主循环遍历文件和插入的列表。在删除了大量样板文件和错误处理后,看起来如下所示: foreach (Document doc in ImportDocs) { using (var dc = new DocumentClassesDataContext(connection)) {

我正试图找出C#应用程序中“内存泄漏”的根源。此应用程序使用SQL Server中的
image
列类型将大量可能较大的文件复制到数据库中的记录中。我正在使用
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事件探查器显示99%的堆由与文件大小相对应的大型
字节[]
对象组成

如果我同时对A行和B行进行注释,则泄漏消失。如果我只取消注释A行,泄漏就会返回。我不明白这是怎么可能的,因为
dc
是为循环的每个迭代处理的

以前有人遇到过这种情况吗?我怀疑直接调用存储过程或执行插入操作将避免此泄漏,但我希望在尝试其他操作之前了解这一点。发生了什么事

更新
包括
GC.Collect()似乎对任何情况都没有重大更改。这并不让我感到惊讶,因为CLR Profiler显示了大量GC事件,但没有显式地诱导它们。

您在哪个操作系统上运行此操作?您的问题可能与Linq2Sql无关,而是与操作系统如何管理大内存分配有关。例如,Windows Server 2008在管理内存中的大型对象方面比XP要好得多。我曾经有过这样的例子:处理大文件的代码在XP上泄漏,但在Win2008服务器上运行良好


HTH

我不完全理解为什么,但是复制一个迭代变量就可以解决这个问题。据我所知,LinqToSql以某种方式在每个文档中制作文档提交的副本

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)
    }
}

你试过给垃圾收集打电话吗。也许不是每次都打,但至少有几次。不是说这是一个解决方案,只是好奇的测试。尤里:这似乎没有什么区别。请参阅我的更新。不记得CLR探查器是否允许您跟踪大字节[]的根-这至少可以告诉您是什么原因导致了它们。我通常使用DevPartner Studio的探查器,它有助于跟踪这些类型的问题。奇怪-我只是尝试在本地重新编程,它工作正常(我用~2M字节[]将数千行写入类型为image的列),并且没有增加进程的内存占用(整个运行时稳定~14M)。你有可能在你的实体类型上定义了一些导致恶作剧的部分方法吗?嗯,我没有2300美元的备用资金,但我会记住这一点。