为什么仍然有这个字符串的引用?
问题描述:
我正在与WeakReference
和WeakReference<T>
Tyoing。他们只使用类(显然,参考),所以我做了一个字符串示例(字符串是.Net中的一个类)。为什么仍然有这个字符串的引用?
当我运行下面的代码片段,它没有提供结果我所料,在该WeakReference
仍含有该字符串的含义。
string please = "wat";
WeakReference<string> test = new WeakReference<string>(please);
string testresult;
please = null;
GC.Collect();
bool worked = test.TryGetTarget(out testresult);
Console.WriteLine("it is " + worked);
结果: “这是真的”
现在,当我创建的字符串围绕一个简单的包装类:
class TestWeakStuff
{
public string Test { get; set; }
}
,并用它来代替字符串,它没有返回我的预期的结果:
TestWeakStuff testclass = new TestWeakStuff() { Test = "wat" };
WeakReference<TestWeakStuff> test2 = new WeakReference<TestWeakStuff>(testclass);
TestWeakStuff testresult2;
testclass = null;
GC.Collect();
bool worked2 = test2.TryGetTarget(out testresult2);
Console.WriteLine("2nd time is " + worked2);
结果:“第二次是假的”
我尝试同样与非通用类WeakReference
,结果是一样的。
为什么String没有被垃圾收集器声明?
(GC.Collect()
并要求各代,外部呼叫模式是-1(万代))
答
字符串文字不是一个很好的候选人,以测试GC行为。字符串文字被添加到CLR上的intern pool。这导致每个不同的字符串文字只有一个对象存在于内存中。这是一个优化。实习生池中的字符串被永久引用,永远不会被收集。
字符串不是普通的类。它们是运行时的内在因素。
你应该能够new string('x', 10)
这将创建一个新的对象,每次来测试它。这是保证如此。有时,这被用于使用不安全的代码写入字符串,然后将它们发布到其他代码。也可以使用本机代码。
这可能是最好的完全放弃测试字符串。您获得的结果并不特别有趣,或者保证在运行时更改时保持稳定。
您可以用new object()
这将是测试它最简单的方法测试。
随意编辑标题,我不知道比这更好。 – Mafii
关于该标题:WeakReference上没有垃圾回收以及具有未引用值的字符串数据类型? –
rfb
延伸阅读:每个人都认为关于垃圾收集错误的方式(https://blogs.msdn.microsoft.com/oldnewthing/20100809-00/?p=13203) – theB