почему стек и куча необходимы для выделения памяти - PullRequest
1 голос
/ 17 июня 2010

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

Ответы [ 5 ]

3 голосов
/ 17 июня 2010

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

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

1 голос
/ 07 июля 2010

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

так же, как парадигма статического выделения *1006* не может обрабатывать рекурсивные вызовы процедур. (например, наивное вычисление фибоначчи (n) как f (n-1) + f (n-2))

Я не знаю простого алгоритма, который бы иллюстрировал этот факт. любые предложения будут оценены: -)

1 голос
/ 17 июня 2010

Неправильно, что типы значений всегда живут в стеке. Прочитайте статью Джона Скита на тему:

Память в .NET - что идет куда

0 голосов
/ 27 сентября 2011

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

Между прочим, в .net одним из основных преимуществ изменяемых типов значений является то, что они могут передаваться по ссылке, не отказываясь от постоянного контроля над ними. Если класс 'foo' или его метод имеет структуру 'boz', которую один из методов foo передает по ссылке на метод 'bar', возможно, что bar или вызываемые им методы будут делать все, что захотят ' boz ', пока они не вернутся, но как только' bar 'вернет все ссылки на' boz ', они исчезнут. Это часто приводит к гораздо более безопасной и чистой семантике, чем разнородные ссылки, используемые для объектов класса.

0 голосов
/ 17 июня 2010

Локальные переменные размещаются в стеке.Если бы это было не так, вы не смогли бы иметь переменные, указывающие на кучу при выделении памяти переменной.Вы МОЖЕТЕ распределить вещи в стеке, если хотите, просто создайте достаточно большой локальный буфер и управляйте им самостоятельно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...