为什么不收集未引用的对象
本文关键字:对象 引用 为什么不 | 更新日期: 2023-09-27 18:03:04
程序输出"True"到控制台
分配一个对象,使其为WeakReference,转到out of block作用域,并检查WeakReference. isalive
public static void Main (string[] args)
{
Test ();
}
static void Test ()
{
WeakReference wref = null;
{ // block scope
var obj = new object ();
wref = new WeakReference (obj);
}
// obj is out of scope
// Console.WriteLine (obj);
GC.Collect ();
Console.WriteLine (wref.IsAlive); // => True
}
为什么不收集obj,虽然obj超出了作用域?
程序由Mono 3.12.0编译。
编辑:对不起,不恰当的例子。
下面的程序也打印True。块范围似乎没有关系。这是在调试模式下尝试的not。
public static void Main (string[] args)
{
Test ();
}
static void Test ()
{
WeakReference wref = null;
var obj = new object ();
wref = new WeakReference (obj);
obj = null;
GC.Collect ();
Console.WriteLine (wref.IsAlive); // => True
}
$ mcs -debug- Program.cs
$ mono Program.exe
我猜是因为你在调试器中运行。
尝试运行发布版本,并在调试器之外手动运行。
您希望GC是100%确定的,当它不是。
一些可能发生的事情:
- JIT优化空赋值。 指向实例的指针可以留在临时堆栈位置,或者在寄存器中(您调用函数,传递变量,这将把变量放在某些体系结构的寄存器中)。
GC结束后。收集,添加:
GC.WaitForPendingFinalizers();
通过调用这个过程,所有可终结的对象都可以在继续程序之前执行任何必要的清理。它确保你的代码不会调用当前正在销毁的对象上的方法。