Есть ли утечка памяти в реализации ConcurrentBag <T>? [Дубликат]

Possible Duplicate:
Possible memoryleak in ConcurrentBag?

Edit1:

Актуальный вопрос Можете ли вы подтвердить это или мой образец неверен, и мне не хватает чего-то очевидного?

Я думал, что ConcurrentBag - просто замена неупорядоченного списка. Но я был неправ. ConcurrentBag добавляет себя в качестве ThreadLocal к потоку создания, что в основном вызывает утечку памяти.

   class Program
    {
        static void Main(string[] args)
        {
            var start = GC.GetTotalMemory(true);
            new Program().Start(args);
            Console.WriteLine("Diff: {0:N0} bytes", GC.GetTotalMemory(true) - start);
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
            Thread.Sleep(5000);
        }

        private void Start(string[] args)
        {
            for (int i = 0; i < 1000; i++)
            { 
                var bag = new ConcurrentBag<byte>();
                bag.Add(1);
                byte by;
                while (bag.TryTake(out by)) ;
            }
        }

Я могу сделать Diff 250 КБ или 100 ГБ в зависимости от того, сколько данных я добавляю в пакеты. Данные, ни сумки уходят.

Когда я врываюсь в это с Windbg, и я делаю ! DumpHeap -type Concurrent

....

000007ff00046858        1           24 System.Threading.ThreadLocal`1+GenericHolder`3[[System.Collections.Concurrent.ConcurrentBag`1+ThreadLocalList[[System.Byte, mscorlib]], System],[System.Threading.ThreadLocal`1+C0[[System.Collections.Concurrent.ConcurrentBag`1+ThreadLocalList[[System.Byte, mscorlib]], System]], mscorlib],[System.Threading.ThreadLocal`1+C0[[System.Collections.Concurrent.ConcurrentBag`1+ThreadLocalList[[System.Byte, mscorlib]], System]], mscorlib],[System.Threading.ThreadLocal`1+C0[[System.Collections.Concurrent.ConcurrentBag`1+ThreadLocalList[[System.Byte, mscorlib]], System]], mscorlib]]
000007feed812648        2           64 System.Collections.Concurrent.ConcurrentStack`1[[System.Int32, mscorlib]]
000007feece41528        1          112 System.Collections.Concurrent.CDSCollectionETWBCLProvider
000007ff000469e0     1000        32000 System.Threading.ThreadLocal`1+Boxed[[System.Collections.Concurrent.ConcurrentBag`1+ThreadLocalList[[System.Byte, mscorlib]], System]]
000007feed815900     1000        32000 System.Collections.Concurrent.ConcurrentStack`1+Node[[System.Int32, mscorlib]]
000007ff00045530     1000        72000 System.Collections.Concurrent.ConcurrentBag`1+ThreadLocalList[[System.Byte, mscorlib]]

Когда я создаю пустой ConcurrentBag, чтобы позволить некоторым рабочим потокам добавлять в него данные, ConcurrentBag и его данные будут там до тех пор, пока создающий поток еще жив.

Таким образом, я получил утечку памяти в несколько ГБ. Я сделал "исправить" это с помощью списка и блокировки. ConcurrentBag может быть быстрым, но бесполезен в качестве простой замены для List с тем же временем жизни объекта.

Если я когда-либо создаю ConcurrentBag в главном потоке, я сохраню его, пока он жив. Это не то, чего я ожидал, и это может вызвать сильную боль.

Ответы на вопрос(3)

Ваш ответ на вопрос