[英]C# Garbage collection
假设我们有:
public void foo()
{
someRefType test = new someRefType ();
test = new someRefType ();
}
垃圾收集器如何处理第一个堆对象? 是否在新分配之前立即进行垃圾回收? 一般机制是什么?
垃圾收集器如何处理第一个堆对象?
谁知道? 这不是确定性的。 想想看这样的:用无限的内存的系统上,垃圾回收器不会做任何事情。 您可能认为这是一个不好的例子,但这就是垃圾收集器为您模拟的:一个具有无限内存的系统。 因为在可用内存多于程序所需内存的系统上,垃圾收集器永远不必运行。 因此,您的程序无法对何时(如果有的话)收集内存做出任何假设。
所以,你的问题的答案是:我们不知道。
是否在新分配之前立即进行垃圾回收?
不。垃圾收集器不是确定性的。 你不知道它什么时候会收集和释放垃圾。 您不能对何时收集垃圾或何时运行终结器做出任何假设。
事实上,它不太可能被收集得如此之快(这会使收集发生得太频繁)。 此外,在具有足够内存的系统上,垃圾收集器永远不必运行。
一般机制是什么?
这是一个相当广泛的问题。 但其基本原理非常简单:垃圾收集器模拟了一台具有无限内存的机器。 为此,它会以某种方式跟踪内存并能够确定内存何时是垃圾。 当它认为合适时,由于需要模拟无限内存,它会不时收集这些垃圾并使其再次可供分配。
不,没有任何内容表明该对象会立即被收集。 事实上,这是不太可能的。 垃圾收集器最终会收集它,但您无法确切知道何时。
您可以通过调用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]
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.