[英]C# weak reference still valid after object GC?
我有一個快速的代碼段可以測試弱引用,我希望在對象成為GC之后,弱引用應該不再返回對象引用。 但是我的測試表明這不是預期的:
class Person
{
private int mI = 3;
public int MI { get => mI; set => mI = value; }
}
class UseWeakReference
{
public static void Main(String[] args)
{
Person person = new Person();
WeakReference<Person> wr = new WeakReference<Person>(person);
wr.TryGetTarget(out Person p1);
Console.WriteLine(p1);
person = null;
wr.TryGetTarget(out Person p2);
Console.WriteLine(p2);
p2 = null;
System.GC.Collect();
Thread.Sleep(1000);
wr.TryGetTarget(out Person p3);
Console.WriteLine(p3); // I expected null here becaure person is collected.
}
}
它打印:
MyApp1.Person
MyApp1.Person
MyApp1.Person // Why still valid?
我在哪里弄錯了?
謝謝。
當您在一個弱引用上調用TryGetTarget
時,假設尚未收集被引用的對象,您將獲得對該對象的強引用。 您在代碼中執行了3次: p1
, p2
和p3
是對該對象的強引用。 當垃圾收集器運行時-自動運行或在您強制垃圾收集時運行-那些強引用將阻止對象的收集。
這是一個有效的版本:
void Main()
{
var person = new Person();
WeakReference<Person> weak = new WeakReference<Person>(person);
person = null;
for (int i = 0; i < 10; i++)
{
Console.WriteLine($"{i}\t{TestReference(weak)}");
Thread.Sleep(100);
}
GC.Collect();
Console.WriteLine(TestReference(weak));
}
class Person
{
private int mI = 3;
public int MI { get => mI; set => mI = value; }
}
bool TestReference(WeakReference<Person> weak)
{
if (weak.TryGetTarget(out Person p))
{
p = null;
return true;
}
return false;
}
請注意,在任何情況下,我們始終都不會對對象保持強大的引用超過幾個周期,並且在垃圾回收器運行時,沒有針對該對象的強大引用,因此無法收集該對象。
即使在這段代碼中,即使我注釋掉p = null;
行中的垃圾收集器可能不會收集對象。 試試看。
這個故事的寓意是:當您從WeakReference<>
獲得強引用時,在完成該操作后, 始終將其WeakReference<>
空。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.