我正在学习C# coming from python,并希望知道C#垃圾收集器是如何工作的--我发现,一旦我弄清楚python在幕后做了什么,我就对python有了更多的了解,并希望避免犯下我在学习python时一开始犯的那种菜鸟错误。
我找不到任何很好的清晰的解释来解释什么时候一个项目被垃圾回收,并且留下了一些问题,比如
对这些问题的回答,或者更好的是,对实际发生的事情进行清晰的概述将赢得cookies (或赞成票),如果您的答案将其与python的做事方式进行比较,则会更好。我对哪个更好不感兴趣,只对细节感兴趣。另外,我在programmers.stackexchange上的原始帖子的答案也将非常感谢…
发布于 2011-03-24 17:17:08
dotnet GC引擎是一个标记和清除引擎,而不是您在python中习惯使用的引用计数器引擎。系统不维护对变量的引用计数,而是在需要回收RAM时运行一个“集合”,标记所有当前可达的指针,并删除所有不可达的指针(因此超出作用域)。
你可以在这里找到更多关于它是如何工作的:
http://msdn.microsoft.com/en-us/library/ee787088.aspx
系统通过从特定的“根”位置开始查找“可达”对象,如全局对象和堆栈上的对象,并跟踪这些对象引用的所有对象,以及这些引用的所有对象,等等,直到它构建了一个完整的树。这比听起来更快。
发布于 2011-03-24 17:16:31
在对象的最后一个引用消失后的某个不确定的时间点,该对象将被收集。
你第一个问题的第二部分没有意义。
如果你能回到定义一个对象的作用域(例如,一个lambda表达式),显然还有一个引用。
GC根本不使用引用计数。
相反,它使用mark-and-sweep algorithm。
发布于 2011-03-24 17:22:03
垃圾收集不会由超出范围的引用触发。垃圾收集通常在为新对象分配存储空间时触发-特别是当第零代的预算耗尽时。即,在对象适合垃圾收集的时间和它们被实际收集的时间之间可能存在显着的延迟。正如其他人已经指出的,CLR不使用引用计数。相反,它采用了一种标记和清除方法。
关于垃圾收集如何工作的所有细节的一个很好的信息来源是Jeffrey Ricther的书CLR via C#。这本书详细介绍了堆是如何分区的,以及垃圾收集是如何工作的。如果您对.NET实现细节感兴趣,强烈建议您使用它。
https://stackoverflow.com/questions/5422918
复制