存在循环引用时有关.NET垃圾收集器的问题

时间:2009-01-24 14:46:20

标签: .net

我知道.net垃圾收集器会检测到循环引用,但我想知道循环引用是否会导致对象停留的时间超过必要的时间。

我的ASP.NET应用程序中有一个循环引用(出于与性能相关的原因),我可以侥幸逃脱吗?

此致

5 个答案:

答案 0 :(得分:11)

不再使用CLR来移除循环引用而不是非循环引用。 CLR使用多种技术组合进行垃圾收集。但快速版本是从所有有根对象(堆栈中的对象,或使用强GC句柄保存)开始。可以从这些对象访问的任何对象都是活动的。将收集任何其他内容。循环引用不会影响此算法的结果,除了CLR必须确保检查它们而不是走在圈内

答案 1 :(得分:4)

它不需要检测周期,因为在它使用的算法中,周期根本不是问题。

如果存在从根(栈中的变量或静态变量,基本上,因为已知它们是实时的,并且不能被GC)到对象的路径,那么该对象必须是也活着,不会得到GC。

如果没有路径,则该对象已死,可以安全地进行GC操作。周期无所谓。所以不,周期不会对象生命周期产生影响。

答案 2 :(得分:1)

基本上,如果任何静态,局部变量,参数或成员变量引用对象,则它不可用于垃圾回收。如果存在循环引用并不重要。参考循环,在这种情况下,不收集循环或不参考,在这种情况下可以收集整个循环。

如果一个类型实现了终结器,它将进行收集,直到它的终结器运行。

答案 3 :(得分:1)

GC将收集根对象未引用的任何对象。 Root对象通常是所有appdomains(即加载的程序集/类型对象)引用的对象,全局和静态对象引用,每个线程各自堆栈上的所有对象引用以及当前加载到CPU寄存器中的任何对象引用。

在收集时,GC会遍历所有已知根对象的引用,并将其在路上找到的任何对象标记为“正在使用”。完成后,可以安全地收集任何未标记的对象。

因此,如果根对象(直接或间接)没有引用任何对象,那么是否存在循环引用并不重要。无论如何,他们都有资格收集。我说符合条件,因为GC使用三种不同的策略来收集符合条件的对象,并且由于性能原因,其中只有一个在运行时收集所有符合条件的对象。

通常你不必考虑这个,它只是有效。但是垃圾收集还有很多,你仍然需要了解它的基本原理,以便了解内存管理并编写不会泄漏资源等的无错误代码。因此,每个.NET开发人员都应该考虑一下。以下是一些资源,可以解释CLR如何进行垃圾收集。

MSDN - Garbage Collector Basics and Performance Hints (Rico Mariani)

MSDN Magazine - Garbage Collection (Part 1): Automatic Memory Management in the Microsoft .NET Framework (Jeffrey Richter)

MSDN Magazine - Garbage Collection (Part 2): Automatic Memory Management in the Microsoft .NET Framework (Jeffrey Richter)

答案 4 :(得分:0)

Java GC可以检测周期并处理它们。我敢打赌,C#GC也可以。