Освобождение памяти стека в .NET

Сегодня я прочитал блог на CodeProject об управлении памятью .NET.

URL - Статья

Он говорит -

Выход из метода (удовольствие): Теперь, наконец, элемент управления выполнением начинает выход из метода. Когда он передает конечный элемент управления, он очищает все переменные памяти, назначенные в стеке. Другими словами, все переменные, относящиеся к типу данных int, освобождаются из стека способом «LIFO».

Большой улов - это не освобождает память кучи. Эта память будет позже освобождена сборщиком мусора.

Насколько я понимаю, сборщик мусора только освобождает память кучи. Итак, кто освободит стековую память?

Пожалуйста, предложите.


person KiddoDeveloper    schedule 13.09.2016    source источник
comment
По умолчанию вызываемый объект отвечает за очистку стека (stdcall соглашение о вызовах).   -  person Frédéric Hamidi    schedule 13.09.2016
comment
Что и где находятся стек и куча.   -  person Groo    schedule 13.09.2016
comment
Контент Codeproject.com не подлежит тщательной проверке. Из-за этого много чепухи и ошибок, включая первый абзац этой цитаты. Ничего не очищается и не освобождается, локальные переменные просто забываются, когда метод возвращается. Мало чем отличается от того, как работает класс .NET Stack ‹›.   -  person Hans Passant    schedule 13.09.2016


Ответы (3)


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

Вы получите StackOverflowException, когда израсходуете все доступное пространство в стеке, хотя это почти наверняка симптом бесконечного цикла (ошибка!) Или плохо спроектированной системы, которая включает почти бесконечные рекурсивные вызовы.

person Debendra Dash    schedule 08.07.2018

Короче:

Память стека не освобождается. Это один блок памяти, который будет использоваться повторно. Каждый раз, когда область объявляет переменные (помещается в стек), она будет выталкиваться при выходе из области видимости.

Поэтому, когда вызывается метод, параметры (значение или ссылочный указатель) помещаются (копируются) в стек и извлекаются из него, когда метод завершается. (всплывающее окно - это просто корректировка указателя (индекса) с памятью)

Вот почему переменные, объявленные в { }, недоступны за }

Этот фрагмент памяти предназначен для каждого потока.

person Jeroen van Langen    schedule 13.09.2016

В .NET переменная находится в стеке, независимо от того, содержит ли она число (тип значения), структуру (полностью размещенную в стеке) или ссылку на объект (т. Е. управляемый адрес объекта, где сам объект находится в куче).

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

Таким образом, не происходит выделения или освобождения каких-либо переменных, поскольку это просто значения, выходящие за пределы области видимости. После того, как переменная выходит за пределы области видимости, сборщик мусора не может достичь фактического объекта (кучи) и в конечном итоге собирает его.

person Groo    schedule 13.09.2016
comment
Объем не имеет значения. GC также может собирать объекты, на которые ссылаются локальные переменные, когда метод еще не завершен. Он даже может собирать this в методе экземпляра. Гарантировать, что это не вызовет никаких проблем, является основной задачей джиттера. - person Hans Passant; 13.09.2016
comment
Это правда, GC оптимизирован для сбора экземпляра объекта, как только он понимает, что переменная больше не используется, даже если она все еще не вышла за пределы своей области действия. Но вопрос OP касался освобождения стека, и я сомневаюсь, что существует реализация CLR, в которой указатель стека перемещается куда-нибудь до того, как переменная действительно выйдет за пределы области видимости. Во всяком случае, ваш комментарий действительно точнее. - person Groo; 13.09.2016