在c#中从函数返回一个字符串时,内存是否被释放?

时间:2009-03-30 14:27:02

标签: c# .net clr

这就是我的意思:

class mycalss
{
   string myfunc()
   {
      string str="hello";
      return str;
   }
}
...
static void main()
{
   string str2;
   str2=myfunc();
   ...
   ...
}

在这种情况下,垃圾收集器是否存在删除str2内容的风险,因为str超出了范围?

7 个答案:

答案 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”字符串很可能由编译器放入字符串表中,而您的字符串变量将引用放到表中的相同条目中​​,以避免保留相同字符串的大量副本。

无论哪种方式,都不要担心它被收集。