ASP.NET:在某些情况下我应该担心内存泄漏吗?[C#]

Gif*_*guy 3 .net c# asp.net garbage-collection memory-leaks

在两个对象相互引用的情况下,我关注垃圾收集......

public class A
{   public readonly B _b;
    public A()
    {   _b = new B(this);
    }
}

public class B
{   public readonly A _a;
    public B(A objA)
    {   _a = objA;
    }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,第三类可以参考A......

public class Foo
{   public A _a = new A(); // A and B are both created here.
    public void Bar()
    {   _a = new A();
    }   // Create a new A (and B)
}
Run Code Online (Sandbox Code Playgroud)

通常,垃圾收集器会处理不再具有任何活动引用的对象.但在这种情况下,A和B对象永远不会丢失所有活动引用,因为它们总是相互引用.

Foo对象用new (和)替换当前A(和B)时,垃圾收集器是否能够清除旧的(和)而不用循环对象引用启动无限循环?ABAB

这是一个严重的问题,因为它是一个ASP.NET应用程序.这些对象将在每个Web请求中多次创建,并且如果垃圾收集器无法清除它们,则可能会延迟服务器重新启动.
可能的负面结果:
<<由于RAM溢出导致Web服务器崩溃.
<< Webserver因无限垃圾收集循环而崩溃.

在这种情况下,.NET如何处理垃圾收集?

Jam*_*acs 7

.NET GC通过跟踪有根引用来工作,例如静态字段和范围内局部变量.它正确处理参考周期.例如,如果A < - > B,但都没有从有根参考引用,则会收集它.

让我们考虑GC如何确定它何时可以回收内存.当CLR尝试分配内存并且内存不足时,它会执行垃圾回收.GC枚举所有有根引用,包括任何线程调用堆栈上的静态字段和范围内局部变量.它将这些引用标记为可访问,并遵循这些对象包含的任何引用,并将它们标记为可访问.它继续此过程,直到它访问了所有可访问的引用.任何未标记的对象都是不可访问的,因此是垃圾.GC压缩托管堆,整理引用以指向它们在堆中的新位置,并将控制权返回给CLR.如果释放了足够的内存,则使用此释放的内存继续分配.如果不,

- 来自http://msdn.microsoft.com/en-us/magazine/cc163491.aspx