Подтвердить что ты не робот

Уничтожение объекта структуры в С#?

Я немного смущен тем, что в С# только ссылочные типы получают сбор мусора. Это означает, что GC выбирает только ссылочные типы для выделения памяти. Итак, что происходит с типами значений, поскольку они также занимают память в стеке?

4b9b3361

Ответ 1

Для начала, находятся ли они в стеке или части кучи, зависит от того, какой контекст они являются частью - если они находятся в ссылочном типе, они все равно будут на куче. (Вы должны подумать, насколько вы действительно заботитесь о разрыве стека/кучи в любом случае - как писал Эрик Липперт, в значительной степени детали реализации.)

Тем не менее, в основном память типа значений восстанавливается при восстановлении контекста - поэтому, когда стек вызывается из возвращаемого вами метода, он "восстанавливает" весь стек стека. Аналогично, если значение типа значения фактически является частью объекта, тогда память возвращается, когда этот объект собирает мусор.

Короткий ответ: вам не нужно беспокоиться об этом:) (Предполагается, что у вас нет ничего, кроме памяти, о которой нужно беспокоиться, конечно - если у вас есть структуры со ссылками на собственные дескрипторы которые требуют освобождения, что несколько иной сценарий.)

Ответ 2

Я немного смущен тем, что в С# только ссылочные типы получают сбор мусора.

Это не факт. Или, вернее, истина или ложность этого утверждения зависят от того, что вы подразумеваете под "собирать мусор". Сборщик мусора, конечно, смотрит на типы ценностей при сборе; эти типы значений могут быть живыми и удерживаться в ссылочном типе:

struct S { public string str; }
...
S s = default(S); // local variable of value type
s.str = M(); 

когда запускает сборщик мусора, он, безусловно, смотрит на s, потому что ему нужно определить, что s.str все еще жив.

Мое предложение: уточнить, что вы подразумеваете под глаголом "получает сбор мусора".

GC выбирает только ссылочные типы для выделения памяти.

Опять же, это не факт. Предположим, что у вас есть экземпляр

class C { int x; }

память для целого будет находиться на собранной мусором куске и, следовательно, будет возвращена сборщиком мусора, когда экземпляр C будет выведен из строя.

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

Итак, что происходит с типами значений, поскольку они также занимают память в стеке?

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

Ответ 3

В этом вопросе слишком много глаголов, например, уничтожено, исправлено, освобождено, удалено. Это не соответствует тому, что на самом деле происходит. Локальная переменная просто перестает быть, стиль норвежского попугая.

Метод имеет единственную точку входа, первое, что случается, это то, что указатель стека процессора настраивается. Создание "фрейма стека", пространство для хранения локальных переменных. CLR гарантирует, что это пространство инициализировано равным 0, а не как функция, сильно используемая в С# из-за определенного правила присваивания.

У метода есть одна точка выхода, даже если код метода наперт несколькими операторами return. В этот момент указатель стека просто восстанавливается до исходного значения. По сути, он "забывает", что локальные переменные где-либо там. Их значения никоим образом не "вычищены", байты все еще существуют. Но они не будут длиться долго, следующий звонок в вашей программе будет перезаписывать их снова. Правило нулевой инициализации CLR гарантирует, что вы никогда не сможете увидеть эти старые значения, которые были бы небезопасными.

Очень, очень быстро, занимает не более одного цикла процессора. Видимый побочный эффект этого поведения на языке С# заключается в том, что типы значений не могут иметь финализатор. Обеспечение дополнительной работы не должно выполняться.

Ответ 4

Тип значения в стеке удаляется из стека, когда он выходит из области видимости.

Ответ 5

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

Ответ 6

типы значений будут освобождены, когда кадр стека будет удален после его выполнения. Я бы предположил, что

Ответ 7

Также хотел бы добавить, что стек находится на уровне потока, а куча находится на уровне домена приложения.

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

Ответ 8

Каждый экземпляр типа значения в .NET будет частью чего-то другого, который может быть более крупным экземпляром типа экземпляра значения, кучевым объектом или фреймом стека. Всякий раз, когда возникает какая-либо из этих вещей, любые структуры внутри них также появятся; эти структуры будут продолжать существовать до тех пор, пока вещь, содержащая их. Когда вещь, которая содержит структуру, перестает существовать, структура будет также. Невозможно разрушить структуру, не разрушая контейнер, и нет способа уничтожить что-то, что содержит одну или несколько структур, не разрушая содержащиеся в нем структуры.