How can I free-up memory used by a Parallel.Task?

前端 未结 2 2147
无人共我
无人共我 2020-12-16 21:34

I have a program that does a memory intensive simulation. Below I\'ve written a small console application that replicates the problem I\'m having.

class Prog         


        
2条回答
  •  粉色の甜心
    2020-12-16 21:59

    This is due to the nature of a concurrentBag (see my earlier question regarding ConcurrentBag ( Possible memoryleak in ConcurrentBag? )).

    Basically, a concurrent bag stores items on the local thread. If you dont consume the items, the items will stay on the local thread. Please check the following example:

        class TrackedItem
        {
            public TrackedItem()
            {
                Console.WriteLine("Constructor!");
            }
            ~TrackedItem()
            {
                Console.WriteLine("Destructor!");
            }
        }
    
        static void Main(string[] args)
        {
            Action allCollect = () =>
                {
                    GC.Collect();
                    GC.WaitForPendingFinalizers();
                    GC.Collect();
                };
    
            // create a single item and loose it directly thereafter
            TrackedItem item = new TrackedItem();
            item = null;
            allCollect();
            // Constructor!, Destructor!
    
            ConcurrentBag bag = new ConcurrentBag();
            bag.Add(new TrackedItem());
            bag = null;
            allCollect();
            // Constructor!
            // Note that the destructor was not called since there is still a collection on the local thread
    
            Console.ReadLine();
        }
    

    The concurrentBag makes use of the ThreadLocal class which makes it convenient to hold 1 instance per thread. The intended way for disposing data in a ThreadLocal is by calling the Dispose method on ThreadLocal (ThreadLocal implements IDisposable). This disposes only the data for the current thread. The concurrentBag doesn't dispose it's ThreadLocals though. Instead it relies on all items being consumed- or a thread hosting the ThreadLocal being disposed. this can be very nasty however when you share threads like within a ThreadPool.

提交回复
热议问题