有没有在ConcurrentBag内存泄漏 实施? [重复](Is there a memo

2019-07-29 16:27发布

可能重复:
在ConcurrentBag可能memoryleak?

EDIT1:

实际的问题是。 你能否证实这个或者是我错了样品和我丢失的财产以后明显?

我还以为是ConcurrentBag为的simpy的unorderd列表的替代品。 但是我错了。 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 KB或100 GB。 该数据也袋消失。

当我打入这个使用WinDbg和我做了!DumpHeap型并发

....

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及其数据将在那里只要创建线程仍然活着的数据。

这样,我得到了几个GB的内存泄漏。 我没有用一个列表和锁“修理”这一点。 ConcurrentBag可能是快,但它是无用的简单替换具有相同对象的生命周期的List。

如果我创建主线程上ConcurrentBag我只要线程是活动的继续使用它。 这不是我所期望的,它可以引起严重的疼痛。

Answer 1:

你是正确的,ConcurrentBag创建一个ThreadLocal副本,实际上他们对场景中的相同线程读取和写入数据包优化的:” ...... ConcurrentBag是线程安全的袋的实施,对场景中的相同优化线程将是既生产和消费存储在数据包。”

在otherhand,我在这里看不到一个奇怪的行为; 螺纹生活和并发袋生活。 当线程完成GC将做的工作。



Answer 2:

从文档

ConcurrentBag是线程安全的袋的实施,对场景中相同的线程将是既生产和消费存储在数据包优化。

从何时使用线程安全集合

在混合生产者 - 消费者的情况,ConcurrentBag一般是多少比任何其他并发集合类型为大型和小型工作负载的速度更快,扩展性更强。

我会说,你对ConcurrentBag的假设是不正确的。 首先,它不添加itsels到ThreadLocal的,它使用线程本地存储用于访问它的每个线程提供单独的内部列表。 它不仅仅是一个线程安全的无序列表多。

你认为是内存泄漏究竟是预期的行为,一旦你意识到袋使用TLS - 没有必要,只要线在使用中清除数据。

说了这么多,我没有意识到ConcurrentBag的自己的额外功能,直到刚才。

我发现的ConcurrentBag如何使用单独的列表一个很好的说明和它的方法在“不同scenarions成本是什么ConcurrentBag ”。 我真的希望这个描述出现在MSDN文档。

就个人而言,我会更多,现在我知道它的特殊行为的开始使用ConcurrentBag很多。

更新:

刚才检查这个职位由Ayende说,“ThreadLocal的,这ConcurrentBag使用,没想到有很多实例,这已得到修复,并且现在可以相当快跑”



Answer 3:

为什么第二GC.Collect的后不动Console.WriteLine命令()? 否则,你可能会寻找一些更多的对象比你预期的。

您也可以尝试把一切都在你的主成一个圈,以得到一些统计数据。 即使你不移动你写,你可能会看到事后小的增量。

干杯!



文章来源: Is there a memory leak in the ConcurrentBag implementation? [duplicate]