为什么还有对这个字符串的引用?
Why is there still a reference onto this string?
我在摆弄 WeakReference
和 WeakReference<T>
。它们只适用于 classes(显然,reference)所以我用字符串做了一个例子(字符串是 .Net 中的 class)。
当我 运行 下面的代码片段时,它没有提供我预期的结果,意思是 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);
result: "it is true"
现在,当我围绕字符串创建一个简单的包装器 class 时:
class TestWeakStuff
{
public string Test { get; set; }
}
并使用它代替字符串,做了 return 我的预期结果:
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);
Result: "2nd time is false"
我对非泛型 WeakReference
class 进行了同样的尝试,结果是一样的。
为什么字符串没有被垃圾收集器回收?
(GC.Collect()
确实声明了所有世代,外部 GC 调用带有 -1(所有世代))
字符串文字不适合测试 GC 行为。字符串文字被添加到 CLR 上的 intern pool。这导致每个不同的字符串文字只有一个对象驻留在内存中。这是一个优化。实习生池中的字符串会被永远引用并且永远不会被收集。
字符串不是普通的class。它们是运行时的固有特性。
您应该能够使用 new string('x', 10)
对其进行测试,它每次都会创建一个新对象。保证如此。有时,这用于在将字符串发布到其他代码之前使用不安全代码写入字符串。也可以与本机代码一起使用。
最好完全放弃测试字符串。您获得的结果不是特别有趣或保证在运行时更改时保持稳定。
您可以使用 new object()
进行测试,这是最简单的测试方法。
我在摆弄 WeakReference
和 WeakReference<T>
。它们只适用于 classes(显然,reference)所以我用字符串做了一个例子(字符串是 .Net 中的 class)。
当我 运行 下面的代码片段时,它没有提供我预期的结果,意思是 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);
result: "it is true"
现在,当我围绕字符串创建一个简单的包装器 class 时:
class TestWeakStuff
{
public string Test { get; set; }
}
并使用它代替字符串,做了 return 我的预期结果:
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);
Result: "2nd time is false"
我对非泛型 WeakReference
class 进行了同样的尝试,结果是一样的。
为什么字符串没有被垃圾收集器回收?
(GC.Collect()
确实声明了所有世代,外部 GC 调用带有 -1(所有世代))
字符串文字不适合测试 GC 行为。字符串文字被添加到 CLR 上的 intern pool。这导致每个不同的字符串文字只有一个对象驻留在内存中。这是一个优化。实习生池中的字符串会被永远引用并且永远不会被收集。
字符串不是普通的class。它们是运行时的固有特性。
您应该能够使用 new string('x', 10)
对其进行测试,它每次都会创建一个新对象。保证如此。有时,这用于在将字符串发布到其他代码之前使用不安全代码写入字符串。也可以与本机代码一起使用。
最好完全放弃测试字符串。您获得的结果不是特别有趣或保证在运行时更改时保持稳定。
您可以使用 new object()
进行测试,这是最简单的测试方法。