为什么仍然有这个字符串的引用?

问题描述:

我正在与WeakReferenceWeakReference<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(万代))

+0

随意编辑标题,我不知道比这更好。 – Mafii

+0

关于该标题:WeakReference 上没有垃圾回收以及具有未引用值的字符串数据类型? – rfb

+1

延伸阅读:每个人都认为关于垃圾收集错误的方式(https://blogs.msdn.microsoft.com/oldnewthing/20100809-00/?p=13203) – theB

字符串文字不是一个很好的候选人,以测试GC行为。字符串文字被添加到CLR上的intern pool。这导致每个不同的字符串文字只有一个对象存在于内存中。这是一个优化。实习生池中的字符串被永久引用,永远不会被收集。

字符串不是普通的类。它们是运行时的内在因素。

你应该能够new string('x', 10)这将创建一个新的对象,每次来测试它。这是保证如此。有时,这被用于使用不安全的代码写入字符串,然后将它们发布到其他代码。也可以使用本机代码。

这可能是最好的完全放弃测试字符串。您获得的结果并不特别有趣,或者保证在运行时更改时保持稳定。

您可以用new object()这将是测试它最简单的方法测试。