2016-09-09 12 views
1

Во-первых, я сейчас работаю на C#, и я читал об управлении памятью. До сих пор я прочитал несколько отличных ответов на переполнение стека, объясняя разницу между памятью стека и управляемой памятью кучи. В большинстве ответов указано, что, объявив:
int x = 5, вы выделяете достаточно памяти для типа x в памяти стека.

Я понимаю, как это работает, а также его объем, однако, когда я прочитал объяснение памяти кучи, это смутило меня.

Если вы говорите int x = 5, поскольку int является псевдонимом System.Int32, не x технически быть указателем на новый экземпляр System.Int32 структуры? И если да, то не будет ли он затем сохранен в памяти кучи, поскольку это используется для объектов типа.

В this учебнике говорится (для линии class1 cls1 = new class1()): Является ли стек памяти только для указателей и кучи для объектов?

... создает указатель на стек и реальный объект сохраняется в другом типе ячейки памяти под названием «Heap».

По этой логике не все хранится в куче и только указатели, хранящиеся в стеке? Примеры быть новые экземпляры System.String, System.Int64, System.Boolean, System.Decimal и т.д.

Я думал, что я понял это, однако очевидно, я не делаю, так что я был бы признателен кто-то объяснял ли стек только для указателей или какая часть я неправильно , Заранее спасибо.

+1

'System.Int32' - это структура, а не класс. Итак, * как локальный *, он, скорее всего, будет выделен в стеке. – vcsjones

+1

Имейте в виду, что.NET CLR меняется, и линии между «выделенной кучей» и «выделенным стеком» продолжают становиться более сумасшедшими. – vcsjones

+0

В этом учебнике сказано: «Время, когда оно попадает в новое ключевое слово, оно выделяется« кучей ».», И когда вы используете структуру (насколько мне известно), вы должны использовать новое ключевое слово. Вот почему я тоже смущен. – Nathangrad

ответ

3

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

Возможные места являются:

  1. Для локальных переменных это стек. Обратите внимание, что физически значения могут храниться в регистре CPU, а не в стеке.
  2. Для полей классов он находится внутри смежного фрагмента памяти, выделенного в куче для экземпляра класса.
  3. Для статических полей он выделяется в кучи загрузчика как часть метаданных типа (исправьте меня, если я ошибаюсь).

Предупреждение: это просто базовое, не всеобъемлющее объяснение, чтобы иметь общее представление о том, что происходит. Реальность более сложная. Локальные переменные могут быть подняты и перемещены в кучу, оптимизатор может полностью их устранить и т. Д.

+1

Для локальных переменных * unhoisted * это может быть стек. См. Сообщение Эрика Липперта, связанное с комментариями, если вы хотите быть точным. –

+0

Да, вставленные переменные становятся полями класса отображения (закрытия) –

+2

И даже если переменная не поднимается, стек может даже не использоваться. Он может строго использовать регистр, или он может быть оптимизирован полностью. – Servy

-1

Вы можете проверить Classes and structs (MSDN), чтобы понять, что хранится, где и как:

int x = 1; // 32 bits holding an integer in the stack 
System.Object bo = x; // 32+some more bits are on the heap to hold the "boxed" (wrapped to be kept on the heap) integer value 
System.Object ho = new Object(); // some bits are created on the heap right from the start 

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

Если вам действительно нужно/хотите понять, как работает CLR в целом, подумайте о чтении «CLR через C#» (Richter).

+0

И тогда вы можете прочитать спецификацию ECMA, если у вас много свободного времени. –

+0

Если вы хотите добавить еще, вы должны отредактировать свой ответ. Там никогда не должно быть необходимости * непосредственно * комментарий на свой вопрос (вопрос/ответ) –

+5

Это сложнее, чем просто «типы значений хранятся в стеке, а ссылочные типы хранятся в куче». – EJoshuaS