是ConcurrentBag导致内存泄漏

本文关键字:内存 泄漏 ConcurrentBag | 更新日期: 2023-09-27 18:24:21

可能重复:
ConcurrentBag中可能存在内存泄漏?

我的应用程序中出现了严重的内存泄漏。我在其中一个方法中添加到本地concurrentBag集合中的所有数据都从未收集过。

这个简单的代码演示了我如何使用它:

void Main()
{
    var l = new List<int>(){1,2,3,4};
    Func(l);
    l.Clear();
    l=null;
}
void Func(List<int> list)
{
    var bag = new ConcurrentBag<int>();
    Parallel.ForEach(list, k=> bag.Add(++k));
    list.Clear();
    foreach(int i in bag) //I know, I doing it wrong.
    {
        list.Add(i);
    }
}

我期望的是:袋子将被创建并按照"Func"的方法处理。

我看到的是:包永远不会被丢弃,保存在Parallel中创建的所有线程。对于每个线程,保存我添加到其中的所有数据。=(

好的,当我把它添加到列表中时,我可以使用"TryTake"从包中删除项目。但空袋子仍然留在记忆中。

现在我通过使用List而不是ConcurrentBag来解决问题。但是我一直睡不好,因为我在记忆中看到了这个。对不起我的eng=)

更新

我改变了我的方法"Func":

void Func(List<int> list)
{
    var bag = new ConcurrentBag<int>();
    Parallel.ForEach(list, k=> bag.Add(++k));
    list.Clear();
    int i;
    while(bag.TryTake(out i))
    {
        list.Add(i);
    }
    bag = null;
    GC.Collect();
    GC.WaitForPendingFinalizers();
}

然后我在VS中创建项目,编译并运行我的程序。这个实例图是由".Net Memory Profiler 4.0"从内存快照中创建的,我在程序完成所有工作后10分钟内收集到:

http://xmages.net/storage/10/1/0/f/d/upload/4c67f305.jpg(抱歉,只是无法发布图像)

是ConcurrentBag导致内存泄漏

这是因为并发包将项目添加到线程的本地存储中。从线的本地存储到袋子的参考是一个强有力的参考,所以只要袋子里还有一件物品,它就确保至少有一根线参考袋子,它就不会被收集。消耗袋子里的所有物品或使用不同的容器。

请参阅:ConcurrentBag中可能存在内存泄漏?