2010-09-16 2 views
4

Можно создать дубликат:
Why are structs stored on the stack while classes get stored on the heap(.NET)?стека и кучи в диез

Может кто-нибудь сказать мне, что, как распределение памяти делается для того, какой объект должен быть сохранен в стеке и которые быть в куче части памяти?

+3

Введите «куча стека C#» в поле поиска выше, и вы быстро найдете нужную вам информацию. –

ответ

5

3 Эмпирические правила:

  1. Объекты хранятся в куче. К ним относятся экземпляры ссылочных типов и типы значений в штучной упаковке.
  2. Локальные переменные и параметры хранятся в стеке. Для локальных значений-значений это означает, что само значение хранится в стеке. Для локальных ссылочных типов в стек будет находиться только ссылка (Edit: Исключения, отмеченные Эриком Липпертом, - локали типа значения, закрытые по внешним переменным, значения-типа-блока).
  3. Поля хранятся там, где находится содержащий экземпляр. Например, поле типа значения класса будет храниться в куче. Эталонная часть поля ссылочного типа структуры, объявленной как локальная, хранящаяся в стеке, также будет находиться в стеке.
+2

Правило 2 неверно. Локальные переменные и параметры не всегда хранятся в стеке. Локальные переменные типа значения, которые являются закрытыми внешними переменными, сохраняются в куче. Все локали типа значения хранятся в куче, если блок является блоком итератора. И, конечно же, вы опускаете тот факт, что * даже местные жители «в стеке» могут быть не в стеке *. Они могут быть зарегистрированы. –

+0

@ Эрик Липперт: Вы правы, конечно; поэтому я поспешил добавить, что это * эмпирические правила *. – Ani

+0

@ Эрик Липперт: Кроме того, не могли бы вы сказать, учитывая то, что компилятор C# делает для блоков итератора, что несколько неточно думать о переменных, объявленных в этих методах как * locals *, в первую очередь? – Ani

12

В реализации Microsoft компилятора C# и CLR типы значений хранятся в стеке, когда значение представляет собой временное значение, локальную переменную или формальный параметр, который не является ни закрытой внешней переменной анонимного метода, ни в блоке итератора.

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

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

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

(И, конечно, отметить, что с помощью «» в «стопке» тонко вводит в заблуждение,. Может быть много стеков в процессе Там не должно быть только один.)

Все это деталь реализации и могут быть изменены без предварительного уведомления.

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

Для получения дополнительной информации по этой теме см мои статьи на нем:

http://blogs.msdn.com/b/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx

http://blogs.msdn.com/b/ericlippert/archive/2009/05/04/the-stack-is-an-implementation-detail-part-two.aspx

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

+0

«Почему вас это волнует?»: Я не могу сказать об этом вопросе, но для меня я искал эту информацию (а также о размере стека) некоторое время назад, поскольку я боялся, что я получу исключение переполнения стека если бы у меня было слишком много структур в стеке. – blizpasta