Ste*_*ven 6 .net c# garbage-collection memory-leaks .net-4.5
我刚刚遇到了垃圾收集者的这种奇怪的"行为" System.Threading.ThreadLocal<T>,我无法解释.在正常情况下,ThreadLocal<T>实例将在超出范围时进行垃圾收集,即使它们没有正确处理,除非它们是循环对象图的一部分.
以下示例演示了此问题:
public class Program
{
public class B { public A A; }
public class A { public ThreadLocal<B> LocalB; }
private static List<WeakReference> references = new List<WeakReference>();
static void Main(string[] args) {
for (var i = 0; i < 1000; i++)
CreateGraph();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
// Expecting to print 0, but it prints 1000
Console.WriteLine(references.Count(c => c.IsAlive));
}
static void CreateGraph() {
var a = new A { LocalB = new ThreadLocal<B>() };
a.LocalB.Value = new B { A = a };
references.Add(new WeakReference(a));
// If either one of the following lines is uncommented, the cyclic
// graph is broken, and the programs output will become 0.
// a.LocalB = null;
// a.LocalB.Value = null;
// a.LocalB.Value.A = null;
// a.LocalB.Dispose();
}
}
Run Code Online (Sandbox Code Playgroud)
虽然不是调用Dispose不是好习惯,但是CLR的设计最终是清理资源(通过调用终结器),即使Dispose没有被调用.
为什么ThreadLocal在这方面表现不同,如果在循环图中没有正确处理,会导致内存泄漏?这是设计的吗?如果是这样,这会记录在哪里?或者这是CLR的GC中的错误?
(在.NET 4.5下测试).
| 归档时间: |
|
| 查看次数: |
370 次 |
| 最近记录: |