Как увеличивается объем стека? - PullRequest
2 голосов
/ 09 июля 2010

В типичной программе на C ядро ​​linux обеспечивает 84–100 КБ памяти.Как ядро ​​выделяет больше памяти для стека, когда процесс использует заданную память.

IMO, когда процесс занимает всю память стека и теперь использует следующую непрерывную память, в идеале это должно произойти сбой страницы итогда ядро ​​обрабатывает ошибку страницы.Здесь ядро ​​обеспечивает больше памяти для стека для данного процесса, и какая структура данных в ядре Linux определяет размер стека для процесса?

Ответы [ 3 ]

2 голосов
/ 10 июня 2011

Существует несколько различных методов, в зависимости от операционной системы (linux realtime vs. normal) и языковой системы времени исполнения:

1) динамический, обычно из-за ошибки страницы

предварительно выделить несколько реальных страниц по старшим адресам и назначить начальный sp для этого.Стек растет вниз, куча растет вверх.Если сбой страницы происходит несколько ниже дна стека, недостающие промежуточные страницы распределяются и отображаются.Эффективно увеличивая стопку сверху вниз автоматически.Обычно существует максимум, до которого выполняется такое автоматическое распределение, которое может или не может быть задано в среде (ulimit), exe-header или динамически настраиваться программой с помощью системного вызова (rlimit).Особенно эта настраиваемость сильно варьируется между различными ОС.Также обычно существует предел того, «насколько далеко» от дна стека ошибка страницы считается нормальной, и может произойти автоматический рост.Обратите внимание, что не все системы стекаются вниз: под HPUX он (используется?) Растет вверх, поэтому я не уверен, что делает Linux на PA-Risc (кто-то может это прокомментировать).

2)фиксированный размер

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

3) По страницам, спагетти и аналогичные

такие механизмы, как правило, забыты, но все еще используютсяв некоторых системах времени выполнения (я знаю системы Lisp / Scheme и Smalltalk).Они распределяют и увеличивают стек динамически по мере необходимости.Однако не как отдельный сегмент, а как связная цепочка многостраничных блоков.Это требует, чтобы компилятор (и) генерировал другой код входа / выхода функции для обработки границ сегмента.Поэтому такие схемы, как правило, реализуются системой языковой поддержки, а не самой ОС (как раньше - вздох).Причина в том, что когда у вас много (скажем, тысяч) потоков в интерактивной среде, предварительное выделение, скажем, 1 МБ просто заполняет ваше виртуальное адресное пространство, и вы не можете поддерживать систему, в которой потребности в потоках отдельного потока ранее неизвестны (что являетсяобычно это происходит в динамической среде, где использование может ввести eval-код в отдельное рабочее пространство).Таким образом, динамическое распределение, как в схеме 1 выше, невозможно, потому что на пути будут другие потоки с их собственными стеками.Стек состоит из небольших сегментов (скажем, 8-64 КБ), которые выделяются и освобождаются из пула и связаны в цепочку сегментов стека.Такая схема может также потребоваться для высокопроизводительной поддержки таких вещей, как продолжения, сопрограммы и т. Д.

Современные Unix / Linux и (я думаю, но не на 100% уверенные) окна используют схему 1) для основного потокаваш exe и 2) для дополнительных (p-) потоков, которым требуется фиксированный размер стека, заданный создателем потока изначально.Большинство встроенных систем и контроллеров используют фиксированное (но настраиваемое) предварительное распределение (даже физически предварительно распределенное во многих случаях).

edit: typo

0 голосов
/ 02 октября 2012

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

0 голосов
/ 09 июля 2010

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

Размер стека для пользовательской программы не определяется ядром. Размер стека ядра - это параметр конфигурации ядра (обычно 4 КБ или 8 КБ).

Редактировать: если вы уже знаете это и просто говорите о выделении физических страниц для процесса, значит, процедура уже закрыта. Но нет необходимости отслеживать «размер стека», как это: виртуальные страницы в стеке без записей в виде страниц являются обычными перезаписанными виртуальными страницами. Физическая память будет предоставлена ​​при первом доступе. Но у ядра нет для перегрузки памяти, и, таким образом, стек, вероятно, будет иметь полную физическую реализацию при первой загрузке исполняемого файла.

...