就在前几天,我正在调查一起内存泄漏事件,在不到两分钟的时间里,应用程序从~50MB膨胀到~130MB。原来问题出在ConcurrentQueue类上。在内部,该类存储数组的链接列表。当一个项从ConcurrentQueue中出列时,数组中的索引会被颠倒,但该项仍保留在数组中(即它没有设置为null)。在足够多的入队/出队之后,整个数组节点都会被删除,所以从技术上讲这并不是泄漏,但如果将大型对象放入ConcurrentQueue中,这可能很快就会失控。文档中没有注意到这种危险。
我想知道基类库中还有哪些潜在的内存缺陷?我知道Substring one (也就是说,如果你调用substring并保持结果不变,整个字符串仍然在内存中)。你还遇到过其他人吗?
发布于 2010-04-21 07:07:57
你是对的。该错误位于方法System.Collections.Concurrent.ConcurrentQueue<T>+Segment.TryRemove(out T, ref ConcurrentQueue<T>.Segment)
中。
如果您在Reflector中查看此方法,您将看到以下行:
result = this.m_array[low];
它后面应该有以下一行:
this.m_array[low] = default(T);
作为参考,您可以看到这是如何在方法System.Collections.Generic.Queue<T>.Dequeue()
中正确实现的。
发布于 2010-04-21 04:22:00
虽然不是直接内存泄漏或特定于.net/BCL,但存在字符串连接(使用+=运算符)问题。由于大量的垃圾收集,这在循环中是相当CPU密集型的。
发布于 2011-04-06 04:37:41
ConcurrentQueue最多只能容纳31个已出列的对象。这不应该是一个大问题,除非你正在处理非常大的对象图。
无论如何,如果你没有足够的空间来分配32个对象,那么使用ConcurrentQueue是没有意义的……
https://stackoverflow.com/questions/2678165
复制相似问题