gpt4 book ai didi

c# - ConcurrentBag 实现中是否存在内存泄漏?

转载 作者:可可西里 更新时间:2023-11-01 08:13:03 24 4
gpt4 key购买 nike

<分区>

Possible Duplicate:
Possible memoryleak in 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)) ;
}
}

我可以将 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,只要该线程处于事件状态,我就会一直保留它。这不是我所期望的,它会导致严重的痛苦。

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com