ConcurrentBag是内存泄漏的原因吗?
可能的重复:
ConcurrentBag 中可能存在内存泄漏?
我的应用程序中存在严重的内存泄漏。我在其中一种方法中添加到本地并发包集合中的所有数据从未被收集。
这个简单的代码演示了我如何使用它:
void Main()
{
var l = new List<int>(){1,2,3,4};
Func(l);
l.Clear();
l=null;
}
void Func(List<int> list)
{
var bag = new ConcurrentBag<int>();
Parallel.ForEach(list, k=> bag.Add(++k));
list.Clear();
foreach(int i in bag) //I know, I doing it wrong.
{
list.Add(i);
}
}
我期望什么:包将在方法“Func”中创建和处置。
我看到的是:bag 永远不会释放,保存在 Parallel.ForEach 中创建的所有线程,保存我添加到其中的所有数据。 =(
好吧,当我将其添加到列表中时,我可以使用“TryTake”从包中删除项目。但是空包仍然保存在内存中。
现在我通过使用 List 而不是 ConcurrentBag 解决了问题。但我睡不好觉因为我在内存分析器中看到了这个。对不起我的工程师 =)
更新
我改变了我的方法“Func”:
void Func(List<int> list)
{
var bag = new ConcurrentBag<int>();
Parallel.ForEach(list, k=> bag.Add(++k));
list.Clear();
int i;
while(bag.TryTake(out i))
{
list.Add(i);
}
bag = null;
GC.Collect();
GC.WaitForPendingFinalizers();
}
然后我在 VS 中创建项目,编译并运行我的程序。该实例图是由“.Net Memory Profiler 4.0”根据内存快照创建的,是我在程序完成所有工作后 10 分钟内收集的:
http://xmages.net/storage/10/1/0/f/d/upload/4c67f305.jpg (抱歉,只是不能发图片)
Possible Duplicate:
Possible memoryleak in ConcurrentBag?
I have epic memory leak in my app. All data, that i add in local concurrentBag collection in one of methods, was never collected.
This simple code demonstrate, how I use it:
void Main()
{
var l = new List<int>(){1,2,3,4};
Func(l);
l.Clear();
l=null;
}
void Func(List<int> list)
{
var bag = new ConcurrentBag<int>();
Parallel.ForEach(list, k=> bag.Add(++k));
list.Clear();
foreach(int i in bag) //I know, I doing it wrong.
{
list.Add(i);
}
}
What I expect: bag will be created and dispose at method "Func".
What I see: bag is never dispose, hold all threads that created in Parallel.ForEach, hold all data, that I add in it. =(
Okay, I can use "TryTake" to remove item from bag, when I add it in list. But empty bag is still hold in memory.
Now I resolve problem by using List instead of ConcurrentBag. But I can't sleep well since I seen this in my memory proflier. Sorry for my eng =)
UPDATE
I change my method "Func":
void Func(List<int> list)
{
var bag = new ConcurrentBag<int>();
Parallel.ForEach(list, k=> bag.Add(++k));
list.Clear();
int i;
while(bag.TryTake(out i))
{
list.Add(i);
}
bag = null;
GC.Collect();
GC.WaitForPendingFinalizers();
}
Then I create project in VS, compile and run my program. This instance graph was been created by ".Net Memory Profiler 4.0" from memory snapshot, that I collect in 10 minutes after program have done all work:
http://xmages.net/storage/10/1/0/f/d/upload/4c67f305.jpg
(sorry, just can't post images)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是因为并发包将项目添加到线程的本地存储中。线程的本地存储对 bag 的引用是强引用,因此只要 bag 中还有 1 个项目,就可以确保至少有 1 个线程引用该 Bag 并且不会被收集。消耗掉袋子中的所有物品或使用不同的容器。
请参阅:ConcurrentBag 中可能存在内存泄漏?
This is because a concurrent bag adds items to the local storage of a thread. The reference from the local storage of a thread to the bag is a strong reference so as long as there is still 1 item in the bag, it ensures that at least 1 thread references the Bag and it wont be collected. Consume all items from the bag or use a different container.
Please see: Possible memoryleak in ConcurrentBag?