内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用
就在前几天,我正在调查一个内存泄露,在两分钟内将应用程序从〜50MB扩展到〜130MB。原来问题出在ConcurrentQueue类。在内部,类存储数组的链表。当一个项目从ConcurrentQueue出队时,数组中的索引被碰撞,但该项目保留在数组中(即它没有设置为null)。整个阵列节点在足够的入队/出队之后被丢弃,所以它在技术上不是泄漏,但是如果在ConcurrentQueue中放入大对象,这可能会很快失去控制。文件没有注意到这种危险。
我想知道基类库中还有哪些潜在的内存缺陷?我知道一个子字符串(也就是说,如果你调用子字符串并只是坚持结果,整个字符串仍然会在内存中)。你遇到过的其他人?
你是对的。该错误位于该方法中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()
。