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

ASP.NET:在某些情况下,我应该担心内存泄漏吗?[C#],c#,.net,asp.net,memory-leaks,garbage-collection,C#,.net,Asp.net,Memory Leaks,Garbage Collection,我关心的是两个对象相互引用时的垃圾收集 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; } } 在这种情况下,第三类可以引用a public class Foo { public A _a

我关心的是两个对象相互引用时的垃圾收集

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;
    }
}
在这种情况下,第三类可以引用
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)
}

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

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

这是一个严重的问题,因为它是一个ASP.NET应用程序。每个web请求都会多次创建这些对象,如果垃圾收集器无法清理它们,这些对象可能会一直保留到服务器重新启动为止。
可能的负面结果:

NET GC通过跟踪根引用工作,例如静态字段和范围内局部变量。它正确地处理引用循环。e、 g.如果A B,但都不是从根引用引用的,则将其收集

我们考虑GC如何决定。 当它可以回收内存时。当 CLR尝试分配内存和内存 没有足够的内存储备,它 执行垃圾收集。GC 枚举所有根引用, 包括范围内的静态字段和 任何线程调用上的局部变量 堆栈它将这些引用标记为 可访问并遵循任何引用 这些对象包含,并将其标记为 也可以到达。它继续这样做 直到它访问了所有 可到达的引用。任何未标记的 对象不可访问,因此 这些都是垃圾。GC压缩 托管堆,整理对 指向他们在中的新位置 堆,并将控制权返回给CLR。 如果释放了足够的内存, 分配使用此方法进行 释放内存。若否,请另加: 从操作系统请求内存 系统


--从

中,.NET垃圾收集器会毫无问题地清理循环引用

它不计算对旧VB6 GC等对象的引用。

它通过遍历内存中从特殊“对象根”开始的所有对象来跟踪活动对象。

如果A->B,B->A并且没有其他对A和B的引用,GC足够聪明来释放这些对象

在ASP.NET中,添加了应用程序池的保险。应用程序的许多实例保存在内存中,并根据需要分配给各种会话。有时,即使在会话的上下文中,IIS也会决定这是刷新应用程序池的好时机。当会话结束时,如果应用程序遇到每个应用程序、每个池或整个系统内存限制,IIS通常会关闭并重新启动应用程序。有时这甚至发生在会话的中间;这在SOA中很常见,在SOA中,外部web层通过WCF与另一台服务器通信,并且web层可以在调用之间刷新服务层。

更简单地说:

当垃圾收集器运行时,它从内存寄存器和静态字段等开始。这些被称为“根”

从这里开始,垃圾收集器跟踪从根到其他对象实例的引用。这将创建可从根访问的所有对象的图形


如果无法从根访问对象,则认为它们未被引用,可以由垃圾收集器清理。

您是否认为这是一个问题?我认为垃圾收集器应该能够检测到原始的
AB
是一个孤岛引用,并且两者都可以安全地删除。“正常情况下,垃圾收集器…-不,它没有:)