11

另请参阅这些相关资源:


换句话说:

是否可以在变量超出范围之前回收由局部变量引用的对象(例如,因为分配了变量,但随后不再使用),或者该对象是否保证在变量超出范围之前没有资格进行垃圾回收范围?

让我解释:


void Case_1()
{
    var weakRef = new WeakReference(new object());

    GC.Collect();  // <-- doesn't have to be an explicit call; just assume that
                   //     garbage collection would occur at this point.

    if (weakRef.IsAlive) ...
}

object在这个代码示例中,我显然必须计划新的被垃圾收集器回收的可能性;因此if声明。

(请注意,我使用weakRef它的唯一目的是检查新版本object是否仍然存在。)


void Case_2()
{
    var unusedLocalVar = new object();
    var weakRef = new WeakReference(unusedLocalVar);

    GC.Collect();  // <-- doesn't have to be an explicit call; just assume that
                   //     garbage collection would occur at this point.

    Debug.Assert(weakRef.IsAlive);
}

与前一个代码示例相比,此代码示例的主要变化是 new'edobject被局部变量 ( unusedLocalVar) 强引用。weakRef但是,在创建弱引用 ( )后,该变量将不再使用。


问题:是否允许符合标准的 C# 编译器将 的前两行优化为仅在一个地方使用的Case_2那些,即作为构造函数的参数?即有没有可能断言 in可能会失败?Case_1unusedLocalVarWeakReferenceCase_2

4

3 回答 3

12

C# 编译器做什么并不重要——只要 JITter/GC 在方法体中不再存在,就可以清理本地引用。查看GC.KeepAlive的文档

此外,这个powerpoint 演示文稿,尤其是从幻灯片 30 开始,有助于解释 JIT/GC 可以做什么。

于 2010-04-30T07:10:27.270 回答
3
于 2011-01-08T09:43:07.277 回答
-1

Is a conforming C# compiler allowed to optimize the first two lines of Case_2 into those of Case_1 if it sees that unusedLocalVar is only used in one place, namely as an argument to the WeakReference constructor?

The two definitions are equivalent so transforming from one to the other is not an "optimization" because neither is more efficient.

i.e. is there any possibility that the assertion in Case_2 could ever fail?

Yes. A production compiler is not likely to retain a reference unnecessarily so it will be removed, the GC will not see it as a global root and will collect that object.

Note that garbage collectors do not see your program in terms of variables and scope. Those high-level concepts have long since been compiled away by the time your code gets to the garbage collector. The GC sees only registers, thread stacks and global variables.

于 2013-01-06T14:40:29.770 回答