.Net Concurrent BlockingCollection有内存泄漏?

时间:2012-10-10 16:55:44

标签: .net memory-leaks blockingcollection

我正在使用Producer/Consumer Pattern System.Collection.Concurrent.BlockingCollection<DataTable&gt;从数据库(生产者)检索数据并在数据(消费者)上创建Lucene索引。

制作人一次抓取10000条记录,并将添加到BlockingCollection<DataTable>。然后消费者(稍微慢一点)抓住那些10000并创建一个索引。

阻塞集合的范围为5 <DataTable>,每行10000行。

一开始程序运行得很好但是在它获得大约150000行之后我注意到我的计算机内存最大化并且它慢慢爬行。

在获取项目后,似乎BlockingCollection无法将基础数组槽设置为null

代码:

    private static LuceneIndex index;
    private static BlockingCollection<DataTable> blockingCol;

    private static void Producer()
    {
        while (true)
        {
            //...get next 10000 rows
            DataTable data = GetNextSet();
            if(data.Row.Count > 0)
                blockingCol.Add(products);
            else
                break;
        }
    }

    private static void Consumer()
    {
        while (!BlockingCol.IsCompleted || BlockingCol.Count > 0)
        {
            DataTable data = blockingCol.Take();
            index.UpdateIndex(GetLuceneDocs(data));
        }
    }


 public static void Main(System.String[] args)
 {
            index = new LuceneIndex();
            blockingCol = new BlockingCollection<DataTable>(2);
            // Create the producer and consumer tasks.
            Task Prod = new Task(Producer);
            Task Con = new Task(Consumer);
            // Start the tasks.
            Con.Start();
            Prod.Start();
            // Wait for both to finish.
            try
            {
               Task.WaitAll(Con, Prod);
            }
            catch (AggregateException exc)
            {
               Console.WriteLine(exc);
            }
            finally
            {
               Con.Dispose();
               Prod.Dispose();
               blockingCol.Dispose();
             }
}

任何人都可以确认拒绝此暂停吗?还有什么工作吗?

1 个答案:

答案 0 :(得分:8)

是的,我可以证实这一点。你不是在.NET 4.5上,是吗?应该在那里修复(你在这个答案下的评论似乎证实了这一点)。

无论如何,在DataTable周围写一个包装器,并在完成表后清除该包装器。这使它符合GC的条件。包装器不会提前GC,但它很小。

class Wrapper<T> { public T Item; }