C# System.WeakReference的奇怪行为
我正在研究C#中的C# System.WeakReference的奇怪行为,c#,reference,weak-references,C#,Reference,Weak References,我正在研究C#中的系统.WeakReference,发现其中有一个奇怪的行为。请查看下面的代码: public class MainClass { public class Fruit { public Fruit(string name) { this.Name = name; } public string Name { get; private set; } } public static void Main()
系统.WeakReference
,发现其中有一个奇怪的行为。请查看下面的代码:
public class MainClass
{
public class Fruit
{
public Fruit(string name) { this.Name = name; }
public string Name { get; private set; }
}
public static void Main()
{
Fruit orange = new Fruit("Orange");
Fruit orangeStrong = orange;
WeakReference orangeWeak = new WeakReference(orange);
orange = null;
orangeStrong = null;
GC.Collect(0, GCCollectionMode.Forced);
GC.WaitForFullGCComplete();
Fruit orangeNew = ((Fruit)orangeWeak.Target);
Console.WriteLine(orangeNew.Name);
}
}
正如预期的那样,此代码会抛出NullReferenceException
,因为orange
是垃圾收集的。但是,在底部添加一行,如下所示:
public class MainClass
{
public class Fruit
{
public Fruit(string name) { this.Name = name; }
public string Name { get; private set; }
}
public static void Main()
{
Fruit orange = new Fruit("Orange");
Fruit orangeStrong = orange;
WeakReference orangeWeak = new WeakReference(orange);
orange = null;
orangeStrong = null;
GC.Collect(0, GCCollectionMode.Forced);
GC.WaitForFullGCComplete();
Fruit orangeNew = ((Fruit)orangeWeak.Target);
Console.WriteLine(orangeNew.Name);
Console.WriteLine(orangeNew == null ? "" : orangeNew.Name);
}
}
使orange
不再被垃圾收集,代码运行时不会出现异常
这种奇怪的行为有什么原因吗?只是检查一下-您是从发布版本而不是调试运行这些,对吗?(调试版本可以延长对象的生命周期)第一个版本也会在调试版本上为我打印“橙色”:当我编译作为发布版本发布的代码并从命令行提示符运行该程序时,两个版本都会崩溃,出现
NullReferenceException
。请注意,无论构建配置或调用GC.Collect()
,从某种意义上说,.NET GC系统都是不确定的,即对象在技术上可能仍然是可访问的,即使您认为您已经使它们无法访问。问为什么某些东西被GC’ed或没有被GC’ed的问题没有那么有用,尤其是你的问题似乎不可靠。