我知道.net垃圾收集器会检测到循环引用,但我想知道循环引用是否会导致对象停留的时间超过必要的时间。
我的ASP.NET应用程序中有一个循环引用(出于与性能相关的原因),我可以侥幸逃脱吗?
此致
答案 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)
答案 4 :(得分:0)
Java GC可以检测周期并处理它们。我敢打赌,C#GC也可以。