в c # при возврате строки из функции освобождается ли память? - PullRequest
1 голос
/ 30 марта 2009

Вот что я имею в виду:

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

В этом случае существует риск, что сборщик мусора может удалить содержимое str2, поскольку str вышел из области видимости?

Ответы [ 7 ]

15 голосов
/ 30 марта 2009

Нет. Детектор мусора увидит, что str2 имеет ссылку на данные, и они не будут собраны.

7 голосов
/ 30 марта 2009

str и str2 являются ссылками на один (строковый) объект. Сборщик мусора будет восстанавливать только те объекты, которые имеют нулевые оставшиеся ссылки.

7 голосов
/ 30 марта 2009

Нет, здесь нет никакого риска. Ссылка будет возвращена, и если сборщик мусора запустится, он сможет увидеть ссылку в main, поэтому не освободит строку.

Обратите внимание, что даже если строка имеет значение , подходящее для сборки мусора, она не будет освобождена немедленно - только при следующем запуске сборщика мусора (или даже позже, в зависимости от того, в каком поколении он заканчивается) .

Обратите внимание, что сборщик мусора может собирать объекты, которые больше не будут использоваться, даже если переменная все еще находится в области видимости - при условии, что она знает, что переменная не будет прочитана снова:

object x = new object();
Console.WriteLine(x);
// Lots more code not touching x
// The object could be collected at any time here
0 голосов
/ 30 марта 2009

Нет, сборщик мусора не удалит содержимое строки по двум причинам:

  • У вас есть ссылка на строку, и до тех пор, пока есть какие-либо активные ссылки на объект, сборщик мусора не удалит его.

  • Это строковый литерал, поэтому он является константой в сборке. Он создается, когда сборка загружается и удаляется, когда сборка удаляется (т.е. когда приложение заканчивается). Сборщик мусора никогда не удалит строковый литерал.

0 голосов
/ 30 марта 2009

Нет. Пока ссылка на одну и ту же строку сохраняется, в этом случае str2. GC не будет собирать его.

0 голосов
/ 30 марта 2009

С тобой все будет хорошо. Строки являются типами значений. Обычно, когда вы возвращаете тип значения, вы на самом деле получаете копию объекта. Поэтому, когда переменная str выходит из области видимости и собирается, ваша переменная str2 будет в порядке.

Теперь, поскольку речь идет о строках , о которых мы здесь говорим, а не только о типе значений, выходящих за рамки обычного, есть и несколько других вещей. Ваша строка "hello", скорее всего, помещена компилятором в таблицу строк, и ваши строковые переменные будут ссылками на эту же запись в таблице, чтобы избежать хранения большого количества копий одной и той же строки. 1011 *

В любом случае, не беспокойтесь о том, что это будет собрано.

0 голосов
/ 30 марта 2009

Неверный ответ:

Строка является неизменной, что, как я считаю, означает, что в вашем примере у вас будет новая копия вашей строки в памяти, поэтому, когда str очищен, str2 имеет свои собственные данные.

разъяснение Джона Скита:

Нет - это обе ссылки на один и тот же строковый объект. Копирует ссылку , а не строку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...