【问题标题】:Why is there still a reference onto this string?为什么还有对这个字符串的引用?
【发布时间】:2016-06-09 12:39:13
【问题描述】:

我正在和WeakReferenceWeakReference<T> 闲聊。它们只适用于类(显然,reference),所以我用字符串做了一个示例(字符串是 .Net 中的一个类)。

当我运行以下代码 sn-p 时,它没有提供我预期的结果,这意味着 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 类进行了同样的尝试,结果是一样的。

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

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

【问题讨论】:

  • 随意编辑标题,我不知道比这更好。
  • 关于标题:没有对 WeakReference 和具有未引用值的 String 数据类型进行垃圾收集?
  • @rfb 我不喜欢 WeakReference 上的垃圾收集,因为 WeakReference 上没有垃圾收集
  • @Mafii 但这正是您所期望的。反正只是一个建议

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


【解决方案1】:

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-01
    • 2011-09-22
    • 1970-01-01
    • 2011-08-04
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多