请参阅下面的代码。我希望它打印 10 之一,因为我已经显式调用了垃圾收集器。但我总是得到 0 或 20 作为输出。这是为什么?
void Main()
{
Panda[] forest_panda = new Panda[10];
for(int i=0; i<forest_panda.GetLength(0);i++)
{
forest_panda[i]=new Panda("P1");
}
for(int i=0; i<forest_panda.GetLength(0);i++)
{
forest_panda[i]=new Panda("P1");
}
System.GC.Collect();
Console.WriteLine("Total Pandas created is {0}",Panda.population);
}
class Panda
{
public static int population=0;
public string name;
public Panda(string name)
{
this.name = name;
population = population + 1;
}
~Panda()
{
population = population - 1;
}
}
请注意,Main 的类是由 LINQPad(《C# 4.0 in a Nutshell》一书附带的编辑器)自动创建的。我是 C# 新手。
您尚未运行显式垃圾收集。从文档GC.Collect() http://msdn.microsoft.com/en-us/library/xe0c2357%28VS.80%29.aspx:
使用此方法尝试回收
所有无法访问的内存。
然而,Collect 方法并不
保证所有不可访问的内存
被回收。
所有物体,无论多长时间
他们一直在记忆中,
考虑收集;然而,
托管中引用的对象
代码不被收集。用这个
强制系统尝试的方法
收回最大金额
有效内存。
垃圾收集器经过高度优化,并且在实际进行垃圾收集时完全由自己“决定”,然后调用终结器。此外,这一切都是异步完成的。这也是 Finalizer 被称为非确定性清理的原因。当清理发生时,你永远不会现在。
你现在有两个选择。您可以致电GC.WaitForPendingFinalizers() http://msdn.microsoft.com/en-us/library/system.gc.waitforpendingfinalizers.aspx这将暂停当前线程,直到所有可终结的对象都被终结。或者称这个新的重载为:System.GC.Collect(int生成,System.GCCollectionMode模式) http://msdn.microsoft.com/en-us/library/bb356724%28VS.90%29.aspx with GCCollectionMode.Forced
它是在 .NET 3.5 中引入的。
请记住,通常没有必要,更重要的是:一个坏主意手动调用垃圾收集器。此外,仅在极少数情况下才需要实现终结器。调用垃圾收集器会减慢运行时间。实现终结器还会进一步减慢运行时间。当所有实现了终结器的对象准备好被垃圾收集时,垃圾收集器会将它们放入终结队列中。处理这个队列的成本很高。
更糟糕的是,当终结器运行时,不能保证您尝试访问的成员仍然存活。它们很可能已经被收集起来了。这就是为什么只有当你有以下情况时才应该使用终结器:不受管理的需要清理的资源。
在您的示例中绝对不需要所有这些。你真正想要的是I一次性 http://msdn.microsoft.com/en-us/library/system.idisposable.aspx用于确定性清理。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)