Gibt es einen Speicherverlust in der ConcurrentBag <T> -Implementierung? [Duplikat]

Mögliche Duplikate:
Mögliches Memoryleak in ConcurrentBag?

Edit1:

Die eigentliche Frage ist. Können Sie das bestätigen oder ist meine Probe falsch und ich vermisse etwas Offensichtliches?

Ich habe gedacht, dass ConcurrentBag einfach ein Ersatz für eine nicht sortierte Liste ist. Aber ich habe mich getäuscht. ConcurrentBag fügt sich dem erstellenden Thread als ThreadLocal hinzu, was im Grunde genommen zu einem Speicherverlust führt.

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

Ich kann Diff auf 250 KB oder 100 GB einstellen, je nachdem, wie viele Daten ich zu den Taschen hinzufüge. Die Daten noch die Taschen gehen weg.

Wenn ich mit Windbg darin einbreche und einen! DumpHeap-Typ Concurrent mache

....

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]]

Wenn ich einen leeren ConcurrentBag erstelle, damit einige Worker-Threads Daten zu ConcurrentBag hinzufügen, sind die Daten dort, solange der erstellende Thread noch aktiv ist.

Auf diese Weise habe ich ein Speicherverlust von mehreren GB. Ich habe dies mit einer Liste und Sperren "behoben". ConcurrentBag ist zwar schnell, aber als einfacher Ersatz für eine Liste mit derselben Objektlebensdauer nutzlos.

Wenn ich jemals einen ConcurrentBag auf dem Haupt-Thread erstelle, behalte ich ihn so lange, wie der Thread aktiv ist. Dies ist nicht etwas, was ich erwarten würde und es kann große Schmerzen verursachen.

Antworten auf die Frage(3)

Ihre Antwort auf die Frage