-->

Is ConcurrentBag cause of memory leak? [duplicate]

2019-05-09 23:57发布

问题:

Possible Duplicate:
Possible memoryleak in ConcurrentBag?

I have epic memory leak in my app. All data, that i add in local concurrentBag collection in one of methods, was never collected.

This simple code demonstrate, how I use it:

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);
    }
}

What I expect: bag will be created and dispose at method "Func".

What I see: bag is never dispose, hold all threads that created in Parallel.ForEach, hold all data, that I add in it. =(

Okay, I can use "TryTake" to remove item from bag, when I add it in list. But empty bag is still hold in memory.

Now I resolve problem by using List instead of ConcurrentBag. But I can't sleep well since I seen this in my memory proflier. Sorry for my eng =)

UPDATE

I change my method "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();
}

Then I create project in VS, compile and run my program. This instance graph was been created by ".Net Memory Profiler 4.0" from memory snapshot, that I collect in 10 minutes after program have done all work:

http://xmages.net/storage/10/1/0/f/d/upload/4c67f305.jpg (sorry, just can't post images)

回答1:

This is because a concurrent bag adds items to the local storage of a thread. The reference from the local storage of a thread to the bag is a strong reference so as long as there is still 1 item in the bag, it ensures that at least 1 thread references the Bag and it wont be collected. Consume all items from the bag or use a different container.

Please see: Possible memoryleak in ConcurrentBag?