可能重复:
ConcurrentBag 中可能存在内存泄漏?
编辑1:
实际的问题是。你能确认一下,还是我的样本错了,我遗漏了一些明显的东西?
我认为 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)) ;
}
}
我可以根据我添加到包中的数据量来制作 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,只要线程还活着,我就会保留它。这不是我所期望的,它可能会导致严重的痛苦。