在.NET并发BlockingCollection有内存泄漏?(The .Net Concurren

2019-09-23 22:27发布

我使用的是生产者/消费者模式与System.Collection.Concurrent.BlockingCollection<DataTable >,以从数据库中检索(生产者)数据和创建数据Lucene索引(消费者)。

生产者抓住10000只记录在一个时间,并增加了设定BlockingCollection<DataTable> 。 消费者(这是有点慢)然后抓住那些10000和创建一个索引。

阻挡集合为界5 <DataTable>的每万行。

起初,程序运行很好,但其获得约15行后,我发现我的电脑内存刷爆它减慢至爬行。

似乎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();
             }
}

任何人都可以证实的拒绝这种悬挂? 而且没有任何解决办法?

Answer 1:

是的,我可以证实这一点。 你是不是在.NET 4.5,是吗? 它应该被固定在那里(和这个答案在你的评论似乎证实了这一点)。

总之,写自己周围的包装DataTable ,并清除包装时,你用表来完成。 这使得它符合GC。 该包装不会早GC'ed但它是很小的。

class Wrapper<T> { public T Item; }


文章来源: The .Net Concurrent BlockingCollection has a memory leak?