代码之家  ›  专栏  ›  技术社区  ›  recursive

LinqToSql InsertOnSubmit内存泄漏?

  •  1
  • recursive  · 技术社区  · 15 年前

    我正试图找出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 byte[] 与文件大小相对应的对象。

    dc 对于循环的每次迭代都会处理。

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

    包括…在内 GC.Collect(); 在第(B)行之后,似乎对任何情况都没有重大变化。这并不让我感到惊讶,因为CLR Profiler显示了大量GC事件,但没有显式地诱导它们。

    2 回复  |  直到 15 年前
        1
  •  0
  •   unclepaul84    15 年前

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

        2
  •  0
  •   recursive    15 年前

    我不完全理解为什么,但制作迭代变量的副本修复了它。据我所知,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)
        }
    }