为什么在这个简单的F#示例中未收集弱引用? [英] Why does the weak reference not get collected in this simple F# example?

查看:40
本文介绍了为什么在这个简单的F#示例中未收集弱引用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

open System

let WeakReferenceExample() =
    let mutable obj = new Object();
    let weak = new WeakReference(obj);

    GC.Collect();
    Console.WriteLine("IsAlive: {0}\nobj <> null is {1}\n---", weak.IsAlive, obj <> null);

    obj <- null;
    GC.Collect();
    Console.WriteLine("IsAlive: {0}", weak.IsAlive);

WeakReferenceExample()
Console.ReadKey()

Rx有效书籍样本.上面的运行时提供了以下输出,与我在C#中编译并运行它后得到的输出不同.

Translated from the Rx In Action book sample. The above when run gives the following output which is different than what I get when I compile it in C# and run it.

IsAlive: True
obj <> null is True
---
IsAlive: True

为什么不收集弱引用?

推荐答案

这是测量影响结果的情况之一.

This is one of those cases where the measurement affects the result.

根本原因是在调试过程中优化了编译器(反向?)以实现更好的本地化.

The underlying cause is compiler (reverse?) optimizations for better locals during Debugging.

撰写时:

let list1 = [1; 2; 3]
let list2 = [3; 4; 5]
printfn "%b" (list1 = list2)

这详细说明了每个子表达式:

This elaborates every sub-expression to:

let list1 = [1; 2; 3]
let list2 = [3; 4; 5] 
let list1' = list1
let list2' = list2
let is_eq = list1'.Equals(list2')
printfn "%b" (is_eq)

现在您可以开始猜测它的去向了.

Now you can begin to guess where this is going.

 Console.WriteLine("IsAlive: {0}\nobj <> null is {1}\n---", weak.IsAlive, obj <> null);

致力于:

    let isAlive = weak.IsAlive
    let obj' = obj
    let isNotNull = obj' <> null
    Console.WriteLine("IsAlive: {0}\nobj <> null is {1}\n---", isAlive, isNotNull);

现在,当您这样做时:

    obj <- null;
    GC.Collect();

请注意, obj'中仍然存在引用.

note that a reference still exists in obj'.

因此,在GC传递期间将不会收集对象.这就是 WeakReference 所显示的.

So the object won't be collected during the GC pass. And that's what WeakReference is showing.

足够有趣的是,如果注释掉第一个 Console.Writeline ,则没有子表达式的详细说明,因此也没有引用,您将得到:

So interestingly enough, if you comment out the first Console.Writeline, there's no sub-expression elaboration, hence no references, and you get:

IsAlive: False

或者您也可以以发布模式构建它.

Or you could just build it in Release mode.

这篇关于为什么在这个简单的F#示例中未收集弱引用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆