C#.NET возражают распоряжению

Должен быть легкий. Скажем, у меня есть следующий код:

void Method()
{
   AnotherMethod(new MyClass());
}

void AnotherMethod(MyClass obj)
{
   Console.WriteLine(obj.ToString());
}

Если я называю "Метод ()", что происходит с объектом MyClass, который был создан в процессе? Это все еще существует в стеке после вызова, даже при том, что ничто не использует его? Или это становится удаленным сразу?

Я должен установить его в NULL, чтобы заставить GC замечать его более быстрый?

8
задан Nick 21 January 2010 в 16:55
поделиться

7 ответов

Если я звоню «Метод ()», что происходит с объектом MyClass, который был создан в процессе?

Это создается на кучи GC. Тогда ссылка на его местоположение в куче помещается на стек. Тогда происходит звонок к другому Method. Затем называется метод ToString объекта, и результат напечатан. Тогда krymethod возвращается.

Это все еще существует в стеке после вызова, хотя это ничто не использует?

Ваш вопрос неоднозначен. По «вызову» вы имеете в виду вызов методу или другому Method? Это имеет значение, потому что на данный момент, является ли память кучи кандидатом для сборки мусора, зависит от того, скомпилированы ли вы с включенными или выключенными оптимизациями. Я собираюсь немного изменить свою программу, чтобы проиллюстрировать разницу. Предположим, что у вас есть:

void Method() 
{ 
   AnotherMethod(new MyClass()); 
   Console.WriteLine("Hello world");
} 

с Optimizations Off, мы иногда на самом деле генерируем код, который будет похож на это:

void Method() 
{ 
   var temp = new MyClass();
   AnotherMethod(temp); 
   Console.WriteLine("Hello world");
} 

в неоптимизированной версии, время выполнения будет на самом деле выбрать для обработки объекта, как не подходит, пока метод не возвращается, после возврата метода Отказ В оптимизированной версии время выполнения может выбрать для обработки объекта как коллекционируемых, как только oneMethod возвращается, перед WriteLine.

Причиной разницы заключается в том, что создание жизни объекта более предсказуема во время сеансов отладки часто помогает людям понять их программы.

Или он сразу удален?

Ничто не собирается сразу; Коллектор мусора бежит, когда ощущается, как он должен бежать. Если вам нужен какой-либо ресурс, такой как файловый дескриптор, который следует сразу убирать, когда вы закончите, затем используйте блок «Использование». Если нет, то пусть сборщик мусора решается, когда собирать память.

Я должен настроить его на NULL, чтобы получить GC, чтобы заметить его быстрее?

Вам нужно установить Что на нуле? Какую переменную вы имели в виду?

Независимо от того, вы не имеют , чтобы сделать все, чтобы сделать коллектор мусора. Он проходит самостоятельно, просто хорошо, не вызывая вас.

Я думаю, что вы перевыпите эту проблему. Пусть сборщик мусора делает свое дело и не подчеркивает об этом. Если у вас есть реальная проблема с памятью, не собираться своевременно, то покажи нам какой-то код, который иллюстрирует эту проблему; В противном случае просто расслабьтесь и научитесь любить автоматическое утилизацию хранения.

7
ответ дан 5 December 2019 в 06:37
поделиться

После завершения вызова к способу ваш объект MyClass жив , но нет никаких ссылок на него из укорениваемого значения. Таким образом, он будет жить до следующего раза в следующий раз, когда GC не работает, где он будет собираться, и память восстановилась.

На самом деле вы не можете сделать, чтобы ускорить этот процесс, отличный от того, чтобы заставить GC. Однако это, вероятно, плохое представление. GC предназначен для очистки таких объектов, и любая попытка, чтобы сделать его быстрее, вероятно, приведет к тому, что он будет медленнее в целом. Вы также найдете, что GC, в то время как правильно очистите управляемые объекты, не могут на самом деле не уменьшить память в вашей системе. Это потому, что GC держит его вокруг для будущего использования. Это очень сложная система, которая обычно лучше всего оставалась на собственных устройствах.

13
ответ дан 5 December 2019 в 06:37
поделиться

На самом деле, экземпляр будет объявлен на куче, но взглянуть на статью Эрика Липпера, Stack - это деталь реализации .

В любом случае, потому что не будет больше ссылок на экземпляр после выполнения функции, это будет (или, точнее, может быть ), удаленный сборщиком мусора на некоторой неопределенной точке в будущее. Что касается именно, когда это произойдет, это не определено, но вы также (по сути) не нужно беспокоиться об этом; GC имеет сложные алгоритмы, которые помогают ему определить, что и когда собирать.

3
ответ дан 5 December 2019 в 06:37
поделиться

Оно все еще существует в стеке после вызова

семантика важно здесь. Вы спросили, существует ли он на стеке после вызова метода. Ответ есть «нет». Это было удалено из стека. Но это не последняя история. Объект все еще существует, он просто не укоренен. Это не будет уничтожено или собрано до тех пор, пока GC не работает. Но на данный момент больше не является вашей проблемой. GC намного лучше принять решение, когда собирать что-то, чем вы или я.

Должен ли я установить его на NULL, чтобы получить GC, чтобы заметить его быстрее?

Во всяком случае, нет никаких веских причин для этого. Единственный раз, когда помогает, если у вас есть очень длительный метод под управлением, и объект, который вы делаете с ранним, что иначе не выйдут вне области действия до конца метода. Даже тогда устанавливая его на NULL, только поможет только в редком случае, когда GC решает запустить во время метода. Но в этом случае вы, вероятно, делаете что-то еще не так хорошо.

3
ответ дан 5 December 2019 в 06:37
поделиться

в C # Новый MyClass () имеет место только для проживания внутри метода (), пока он активен. После того, как это заканчивается unhermethod (). Затем он остается на куче, пока GC не запускает цикл сбора и идентифицирует его как неразрешенный блок памяти. Так что это все еще "жив" на куче, но он недоступна.

2
ответ дан 5 December 2019 в 06:37
поделиться

Насколько я знаю, объект действителен только внутри вашего контекста метода. После того, как метод «Метод ()» выполнен его добавляется в очередь убытки.

-4
ответ дан 5 December 2019 в 06:37
поделиться

GC отслеживает то, какие объекты могут по-прежнему ссылаться позже в коде. Затем, через промежутки времени, проверяет, есть ли какие-либо объекты, которые еще живы, которые не могли быть ссылаться в позже в коде и очистить их.

Механика этого являются несколько сложными, и когда эти коллекции произойдут, зависит от различных факторов. GC предназначен для выполнения этих коллекций в наиболее оптимальное время (что он может установить), и поэтому, хотя можно заставить его сделать коллекцию, это почти всегда плохое представление.

Установка переменной к NULL будет иметь очень мало общего влияния на то, как скоро справится объект. Хотя он может, в некоторых небольших угловых случаях, оказывайтесь на пользу, не стоит мутать кода с резервными заданиями, которые не повлияют на производительность ваших кодов и только для чтения нанесения вреда.

GC предназначен, чтобы быть максимально эффективным, без необходимости думать об этом. Если честно, единственное, что вам действительно нужно помнить о том, чтобы быть осторожным при выворе действительно больших предметов, которые долго останутся в живых, и это вообще довольно редко в моем опыте.

1
ответ дан 5 December 2019 в 06:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: