Стек программ и куча, как они работают? - PullRequest
27 голосов
/ 14 января 2010

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

  1. Является ли стек также частью некоторой страницы в основной памяти?
  2. Что происходит, когда программа переводится в состояние ожидания? Где хранятся указатель стека, программный счетчик и другая информация?
  3. Почему стек растет, а куча растет?
  4. Может ли кэш L1, L2 содержать только один кусок непрерывной памяти, или он может иметь некоторую часть стека и кучи?

Можете ли вы порекомендовать какую-нибудь хорошую книгу, которая охватывает эти вещи?

Ответы [ 5 ]

14 голосов
/ 14 января 2010
  1. Да - стек обычно хранится в «младших» адресах памяти и заполняется вверх до верхнего предела. Куча обычно хранится в «верху» адресного пространства и увеличивается в направлении стека.

  2. O / S хранит «контекст» для каждого запущенного процесса. Операция сохранения и восстановления состояния процесса называется «переключением контекста».

  3. Просто соглашение AFAIK. Стек на самом деле не «растет», он имеет фиксированное распределение.

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

Я бы предложил Архитектура компьютера: количественный подход в качестве хорошего справочника по базовому оборудованию и любой книге по операционным системам о том, как аппаратно "управляться".

7 голосов
/ 14 января 2010

Это мое понимание этих вопросов:

  1. Является ли стек также частью некоторой страницы в основной памяти?

    Да, стек обычно также сохраняется в адресном пространстве процесса.

  2. Что происходит, когда программа переводится в состояние ожидания, где хранятся указатель стека, счетчик программы и другая информация?

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

  3. Почему стек увеличивается, а куча растет?

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

  4. Может ли кэш L1, L2 содержать только один кусок непрерывной памяти или может иметь некоторую часть стека и кучи?

    Кэши ЦП будут хранить недавно использованные фрагменты памяти. Поскольку и стек, и куча хранятся в основной памяти, кэши могут содержать части обоих.

3 голосов
/ 14 января 2010

3. Почему стек растет, а куча растет?

Обратите внимание, что в некоторых системах (например, в некоторых системах HP) стек увеличивается вверх , а не вниз. А в других системах (например, IBM / 390) реальный аппаратный стек отсутствует вообще, а есть пул страниц, которые динамически выделяются из памяти пространства пользователя.

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

1 голос
/ 14 января 2013

Вы должны проверить слайды моего профессора , из моего класса архитектуры. Блок 6. Действительно помог мне понять, все, что вы просили, и другие ответили, и БОЛЬШЕ, если вы хотите более глубокие знания.

1 голос
/ 14 января 2010

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

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

Обычно PUSH приводит к уменьшению указателя стека, оставляя значение выше значения указателей стека "в стеке".

Другая часть памяти может использоваться для кучи. Это тогда доступно для распределения с использованием malloc или new. Каждый поток должен иметь свой собственный стек, но может совместно использовать кучу с другими потоками в процессе.

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

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

...