执行SqlBulkCopy时内存泄漏

c# sql sqlbulkcopy

我遇到了以下代码中发生的错误内存泄漏:

 public void BulkInsert(string tableName, IDataReader reader, String connectionString)
    {
        using (var connection = new SqlConnection(connectionString))
        {
            connection.Open();
            using (var bulkCopy = new SqlBulkCopy(connection))
            {
                bulkCopy.DestinationTableName = tableName;
                bulkCopy.BulkCopyTimeout = 900;

                try
                {
                    bulkCopy.WriteToServer(reader);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
                finally
                {
                    reader.Close();
                }
            }
        }
    }

此代码段执行数千次,因此只需要一分钟就会发生内存不足异常。 Ants报告这是因为GC没有收集IDataReader指向的行。然而,当我注释掉以下行时,没有泄漏,这就是我如何将问题隔离到这个代码。

bulkCopy.WriteToServer(reader);

有没有人建议如何防止内存泄漏?

先谢谢你。

来电代码:

 var reader = datatable.CreateDataReader();
 BulkInsert(tablename, reader, connectionString);
 reader.Dispose();
 datatable.Dispose();

一般承认的答案

我绝对不喜欢回答我自己的问题,但我终于找到了解决办法,虽然我觉得这个错误让我感到愚蠢,但我只是想把它作为答案发布,万一其他人遇到这个问题,所以没有其他人浪费宝贵的时间在这上面。

内存泄漏根本没有提供的代码段 - 实际上它根本不是泄漏...

看一下性能分析我发现速度BulkCopy调用是我整个程序的瓶颈。我有一个生产者 - 消费者模式,它为DataTables提供插入。

我以为Memory Profiler向我展示了DataTable对象,这些对象在我运行代码时没有被处理掉。这些实际上排队的表等待插入,但因为我重新使用测试数据,排队的表已经在DB中(因此似乎已经插入)。

通过注释BulkCopy线我实际上消除了瓶颈,DataTables被迅速处理,因此Memory Profiler上没有显示任何问题。这使得它看起来像Bulkcopy线路有问题。

当我用1秒延迟替换BulkCopy代码时,这还不足以成为瓶颈。只有当我用5s延迟替换BulkCopy时,我注意到我的消费者生产者队列大小失控......因此我为什么快速耗尽内存。

感谢所有花时间在这个问题上的人。对不起它没有更有趣的答案。


热门答案

您可能需要处理读取器以便GC收集它。在您的finally块尝试调用Dispose。

finally
{
    //reader.Close();
    reader.Dispose();
}


许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因
许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因