Czy występuje przeciek pamięci w implementacji ConcurrentBag <T>? [duplikować]

Możliwy duplikat:
Możliwa pamięć pamięci w ConcurrentBag?

Edytuj1:

Rzeczywiste pytanie brzmi: Czy możesz to potwierdzić, czy moja próbka jest błędna i brakuje mi czegoś oczywistego?

Pomyślałem, że ConcurrentBag jest prostym zamiennikiem nieuporządkowanej listy. Ale byłem w błędzie. ConcurrentBag dodaje się jako wątek lokalny do wątku tworzącego, co zasadniczo powoduje wyciek pamięci.

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

Mogę zrobić Diff 250 KB lub 100 GB w zależności od ilości danych dodanych do toreb. Dane ani torby nie odchodzą.

Kiedy włamuję się do tego z Windbg i wykonuję! 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]]

Kiedy tworzę pustą torbę ConcurrentBag, aby niektóre wątki robocze dodawały do ​​niej dane, ConcurrentBag i jej dane będą tam, dopóki wątek tworzący wciąż będzie żył.

W ten sposób dostałem przeciek pamięci o pojemności kilku GB. Naprawiłem to, używając Listy i blokad. ConcurrentBag może być szybki, ale jest bezużyteczny jako prosty zamiennik listy o tym samym czasie życia obiektu.

Jeśli kiedykolwiek utworzę ConcurrentBag na głównym wątku, zachowam go tak długo, jak długo wątek żyje. To nie jest coś, czego bym się spodziewał i może spowodować poważny ból.

questionAnswers(3)

yourAnswerToTheQuestion