.NET Framework - 可能的内存泄漏类?

Rob*_*ser 16 .net c# memory-leaks

就在前几天,我正在调查内存泄漏,该应用程序在两分钟内将应用程序从大约50MB膨胀到大约130MB.事实证明问题出在ConcurrentQueue类.在内部,该类存储数组的链接列表.当一个项目从ConcurrentQueue出队时,数组中的索引会被碰撞,但该项目仍保留在数组中(即它未设置为null).在足够的排队/出队之后,整个阵列节点被丢弃,因此从技术上讲它不是泄漏,但是如果在ConcurrentQueue中放置大对象,这可能会很快失控.文档没有记录这种危险.

我想知道基类库中还有其他潜在的内存缺陷吗?我知道Substring one(也就是说,如果你调用substring并保持结果,整个字符串仍将在内存中).你遇到过的其他人吗?

Sam*_*ell 11

你是对的.该错误位于该方法中System.Collections.Concurrent.ConcurrentQueue<T>+Segment.TryRemove(out T, ref ConcurrentQueue<T>.Segment).

如果您在Reflector中查看此方法,您将看到以下行:

result = this.m_array[low];
Run Code Online (Sandbox Code Playgroud)

它之后应该有以下行:

this.m_array[low] = default(T);
Run Code Online (Sandbox Code Playgroud)

作为参考,您可以看到在方法中如何正确实现它System.Collections.Generic.Queue<T>.Dequeue().


las*_*sen 0

虽然不是直接内存泄漏或特定于 .net/BCL,但存在字符串连接(使用 += 运算符)问题。由于大量的垃圾收集,循环中的 CPU 消耗相当大。

  • VS C# 编译器也足够智能,可以在内部将 ("This " + "is" + " string #" + stringNumber) 等表达式转换为 StringBuilder(如果这样做有意义的话)。 (2认同)
  • @Dan Bryant:幸运的是你是不正确的。对于您提到的情况,编译器实际上会发出对 string.Concat("This is string#", stringNumber)` 的调用。尽可能组合文字,并且调用“string.Concat”,因为对于固定数量的附加操作,它比“StringBuilder”更快。 (2认同)