C#垃圾收集

说我们有:

public void foo() { someRefType test = new someRefType (); test = new someRefType (); } 

垃圾收集器对第一个堆对象做了什么? 是否在新任务之前立即收集垃圾? 一般机制是什么? 谢谢,Juergen

垃圾收集器对第一个堆对象做了什么?

谁知道? 这不是确定性的。 可以这样想:在具有无限内存的系统上,垃圾收集器不需要做任何事情 。 你可能认为这是一个糟糕的例子,但这就是垃圾收集器为你模拟的东西:一个拥有无限内存的系统。 因为在具有比程序所需的足够大的可用内存的系统上,垃圾收集器永远不必运行。 因此,您的程序无法对何时收集内存(如果有)进行任何假设。

所以,你的问题的答案是:我们不知道。

是否在新任务之前立即收集垃圾?

不。垃圾收集器不确定。 你不知道什么时候会收集和释放垃圾。 您无法对何时收集垃圾或何时运行终结器做出任何假设。

实际上,它收集的速度非常快(这会使收集过于频繁)。 此外,在具有足够内存的系统上,垃圾收集器永远不必运行。

一般机制是什么?

这是一个相当广泛的问题。 但基本原理非常简单:垃圾收集器模拟具有无限内存的机器。 为此,它以某种方式跟踪内存并能够确定内存何时是垃圾。 当它认为合适时,由于需要模拟无限内存,它将不时收集这些垃圾并使其可用于再次分配。

不,没有任何东西可以说立即收集对象。 事实上,它不太可能。 最终将由垃圾收集器收集,但您无法准确知道何时。

您可以通过调用GC.Collect强制收集,但通常不建议这样做。

垃圾收集的确切工作原理是一个相当大的主题,但是你可以在MSDN上阅读很好的文档。

垃圾收集有许多不同的策略,多年来它们变得更加复杂和高效。 在文献和网络上有很多关于它们的优秀资源。 但我也发现有时候一个不完美和丰富多彩的比喻给了我一个帮助我开始的直觉。 所以请允许我尝试:

.NET有一个所谓的“世代”垃圾收集器,我认为它表现得很像我自己。 我让脏衣服和邮件(“C#物品”)在我的客厅地板(“记忆”)上堆积了几天,当我发现我再也看不到地毯了(“记忆已满”)我花了一些时间清理(“垃圾收集”)起居室(“第0代”),丢弃不再需要的物品(“不再可以”)并将剩余的物品移到我的卧室( “第1代”)。 这通常会给我带来一些时间,我不需要再做任何工作了。 但当我的卧室填满时,我做了类似的事情,抛弃了一些物品并将其他物品移到我的地下室(“第2代”)。 偶尔甚至地下室填满,然后我有我真正的问题,需要做一些主要的春季大扫除(“完整收集”)。

将这个比喻应用到你的例子中,我们可能会猜到第一块垃圾(“堆对象”)只是四处闲逛,直到我开始捡起它(“运行第0代收集器”),这种情况发生在我感觉到的时候,当地板被完全覆盖,或者永远不会:-)

要查看对象何时被删除,您可以覆盖类中的finalize方法以打印何时以及删除哪些对象,如下面的示例所示:

 class MyClass { private int _id; public MyClass(int id) { _id = id; } ~MyClass() { Console.WriteLine("Object " + _id + " deleted at " + DateTime.Now + " ."); } } class Program { static void Main(string[] args) { MyClass p1 = new MyClass(1); p1 = new MyClass(2); Console.ReadKey(); } } 

要强制垃圾收集器更快地释放这些对象,可以将一个字段作为长数组添加到它们,类似于private int []memory; 并在构造函数中: memory=new int[10000000]