使用 ConcurrentQueue
时出现了内存泄漏:
requestObject request = xxx;
Item obj= new Item ();
obj.MessageReceived += obj_MessageReceived;
obj.Exited += obj_Exited;
request.Key = obj.Key;
obj.AddRequest(request);
_queue.TryAdd(obj.Key, obj);
在“Exited”回调中,我处理了资源的释放:
void LiveSphere_Exited(string key)
{
Item instance;
_queue.TryRemove(key, out instance);
Task.Factory.StartNew(() =>
{
var wait = new SpinWait();
while (instance.MessageCount > 0)
{
wait.SpinOnce();
}
})
.ContinueWith((t) =>
{
if (instance != null)
{
//Cleanup resources
instance.MessageReceived -= obj_MessageReceived;
instance.Exited -= obj_Exited;
instance.Dispose();
instance = null;
}
});
}
当我对代码进行分析时,我仍然有一个根据“Item”对象引用的对象,但我不知道在哪里可以释放它...
已经触发了退出方法并且队列中已经删除了“Item”对象。
当我阅读文档时,ConcurrentQueue会将引用复制到队列中。
您能帮我找出内存泄漏的原因吗?
ConcurrentQueue
中存在内存泄漏问题,但在4.5版本中已经修复。您可以考虑研究BlockingCollection
,它是一个更好的并发集合的封装。默认情况下,它内部使用ConcurrentQueue
。 - Jim MischelConcurrentQueue
是有泄漏的 - 主要是因为只有在你没有经常使用它时才会发生这种情况(直到弹出了几个项目后,它才会将数据设置为null
) - 那么,使用ConcurrentQueue
还有什么意义呢? - Cory NelsonBlockingCollection
是ConcurrentQueue
的包装器。所以,是的,它是FIFO。 - Jim Mischel