为什么在这个简单的 F# 示例中没有收集到弱引用?
Why does the weak reference not get collected in this simple F# example?
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 In Action 样书。上面的 运行 给出了以下输出,这与我在 C# 和 运行 中编译它时得到的输出不同。
IsAlive: True
obj <> null is True
---
IsAlive: True
为什么没有收集到弱引用?
这是测量影响结果的情况之一。
根本原因是编译器(反向?)在调试期间针对更好的局部变量进行了优化。
当你写:
let list1 = [1; 2; 3]
let list2 = [3; 4; 5]
printfn "%b" (list1 = list2)
这将每个子表达式详细说明为:
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)
现在你可以开始猜测这是怎么回事了。
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'
中仍然存在引用。
因此对象不会在 GC 传递期间被收集。
这就是 WeakReference
所展示的。
非常有趣,如果您注释掉第一个 Console.Writeline
,则没有子表达式详细说明,因此没有引用,您会得到:
IsAlive: False
或者您可以在 发布 模式下构建它。
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 In Action 样书。上面的 运行 给出了以下输出,这与我在 C# 和 运行 中编译它时得到的输出不同。
IsAlive: True
obj <> null is True
---
IsAlive: True
为什么没有收集到弱引用?
这是测量影响结果的情况之一。
根本原因是编译器(反向?)在调试期间针对更好的局部变量进行了优化。
当你写:
let list1 = [1; 2; 3]
let list2 = [3; 4; 5]
printfn "%b" (list1 = list2)
这将每个子表达式详细说明为:
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)
现在你可以开始猜测这是怎么回事了。
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'
中仍然存在引用。
因此对象不会在 GC 传递期间被收集。
这就是 WeakReference
所展示的。
非常有趣,如果您注释掉第一个 Console.Writeline
,则没有子表达式详细说明,因此没有引用,您会得到:
IsAlive: False
或者您可以在 发布 模式下构建它。