为什么还有对这个字符串的引用?

时间:2016-06-09 12:39:14

标签: c# .net reference garbage-collection weak-references

我和WeakReference以及WeakReference<T>一起玩耍。它们只适用于类(显然,引用)所以我用一个字符串做了一个例子(字符串是.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);
  

结果:&#34;这是真的&#34;

现在我在字符串周围创建了一个简单的包装类:

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);
  

结果:&#34;第二次是假&#34;

我尝试使用非泛型WeakReference类,结果是一样的。

为什么垃圾收集器没有声明字符串?

GC.Collect()确实声称所有代,外部GC调用是-1(所有代))

1 个答案:

答案 0 :(得分:1)

字符串文字不适合测试GC行为。字符串文字被添加到CLR上的http://www.fastgraph.com/help/bmp_header_format.html。这导致每个不同的字符串文字只有一个对象存在于内存中。这是一个优化。实习池中的字符串将永久引用,永远不会被收集。

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

您应该能够使用new string('x', 10)对其进行测试,每次都会创建一个新对象。这保证是这样的。有时,这会被用来使用不安全的代码在将字符串发布到其他代码之前写入字符串。也可以使用本机代码。

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

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