我知道我应该只对大对象使用 WeakReference,但我对以下场景感到好奇:
object obj = 1; //Int32
var wk = new WeakReference(obj);
Console.WriteLine(wk.IsAlive); //Prints: True
obj = null;
GC.Collect(2, GCCollectionMode.Forced, true);
Console.WriteLine(wk.IsAlive); //Prints: false, All Rigth!
到目前为止一切正常。
看这个:
object obj = "test"; //String
var wk = new WeakReference(obj);
Console.WriteLine(wk.IsAlive); //Prints: True
obj = null;
GC.Collect(2, GCCollectionMode.Forced, true);
Console.WriteLine(wk.IsAlive); //Prints: True, Why?
这是怎么回事?
最佳答案
来自String.Intern
的评论:
The common language runtime conserves string storage by maintaining a table, called the intern pool, that contains a single reference to each unique literal string declared or created programmatically in your program. Consequently, an instance of a literal string with a particular value only exists once in the system.
因此,还有一个不能以编程方式发布的引用。稍微更改代码以在运行时生成一个实例会得到预期的结果:
object obj = new string(new char[] { 't', 'e', 's', 't' });
var wk = new WeakReference(obj);
Console.WriteLine(wk.IsAlive); //Prints: True
obj = null;
GC.Collect(2, GCCollectionMode.Forced, true);
Console.WriteLine(wk.IsAlive); //Prints: False
关于c# - 包装字符串的 WeakReference 会导致奇怪的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30083227/