这就是我的意思:
class mycalss
{
string myfunc()
{
string str="hello";
return str;
}
}
...
static void main()
{
string str2;
str2=myfunc();
...
...
}
在这种情况下,垃圾收集器是否存在删除str2内容的风险,因为str超出了范围?
答案 0 :(得分:15)
没有。垃圾检测器将看到str2具有对数据的引用,并且不会被收集。
答案 1 :(得分:7)
不,这里没有风险。将返回引用,如果垃圾收集器运行,它将能够在main
中看到引用,因此它不会释放该字符串。
请注意,即使字符串 符合垃圾回收条件,也不会立即释放它 - 只有当垃圾收集器下次运行时(或者甚至更晚,取决于它最终生成的是哪一代) )。
请注意,垃圾收集器可以收集不再使用的对象,即使变量仍在范围内 - 只要它知道该变量将不再被读取:
object x = new object();
Console.WriteLine(x);
// Lots more code not touching x
// The object could be collected at any time here
答案 2 :(得分:7)
str和str2都是对一个(字符串)对象的引用。垃圾收集器只会回收剩余引用为零的对象。
答案 3 :(得分:0)
没有。只要保持对相同字符串的引用,在这种情况下由str2保存。 GC不会收集它。
答案 4 :(得分:0)
不,垃圾收集器不会删除字符串的内容,原因有两个:
您有对字符串的引用,只要有对象的任何活动引用,垃圾收集器就不会删除它。
这是一个字符串文字,所以它是程序集中的常量。它是在组件被移除时(即当应用程序结束时)加载和移除组件时创建的。垃圾收集器永远不会删除字符串文字。
答案 5 :(得分:-1)
答案不正确:
String是不可变的,我相信这意味着在你的例子中,你将在内存中有一个新的字符串副本,所以当str被清理时,str2有自己的数据。
Jon Skeet的澄清:
不 - 它们都是对同一个字符串对象的引用。它复制引用而不是字符串。
答案 6 :(得分:-2)
str
变量超出范围并被收集时,您的str2
变量就可以了。
现在,因为这些是字符串,我们在这里谈论的并不仅仅是任何普通的值类型,还有其他一些事情正在发生。您的“hello”字符串很可能由编译器放入字符串表中,而您的字符串变量将引用放到表中的相同条目中,以避免保留相同字符串的大量副本。
无论哪种方式,都不要担心它被收集。