Примечание : если вам нужно рассмотреть конкретную ОС, чтобы иметь возможность ответить, рассмотрите Linux.
Всякий раз, когда я запускаю программу, ей предоставляется пространство для виртуальной памяти, с областью для ее стека и одной для ее кучи.
Вопрос 1 : имеют ли стек и куча ограничение по статическому размеру (например, 2 гигабайта в каждом), или это ограничение динамическое, изменяющееся в соответствии с распределением памяти во время выполнения программы (то есть всего 4 гигабайта, которые будут использоваться оба, так что, если программа использует только стек, она сможет иметь стек с 4 гигабайтами)?
Вопрос 2 : Как определяется предел? Это общая доступная оперативная память?
Вопрос 3 : Как насчет текста (кода) и разделов данных, как они ограничены?
Ответы:
Есть два разных предела памяти. Ограничение виртуальной памяти и ограничение физической памяти.
Виртуальная память
Виртуальная память ограничена размером и расположением доступного адресного пространства. Обычно в самом начале выполняется исполняемый код и статические данные, а в прошлом - куча, а в конце - область, зарезервированная ядром, перед ним разделяемые библиотеки и стек (который на большинстве платформ уменьшается). Это дает пространство для кучи и стека для роста, остальные области известны при запуске и исправлении.
Свободная виртуальная память изначально не помечается как используемая, но помечается таковой во время выделения. Хотя куча может увеличиваться до всей доступной памяти, большинство систем не наращивают стеки автоматически. Предельное значение по умолчанию для стека IIRC составляет 8 МБ в Linux и 1 МБ в Windows и может быть изменено в обеих системах. Виртуальная память также содержит любые отображенные в памяти файлы и оборудование.
Одна из причин, по которой стек не может быть автоматически увеличен (произвольно), состоит в том, что многопоточным программам требуется отдельный стек для каждого потока, поэтому они в конечном итоге будут мешать друг другу.
На 32-разрядных платформах общий объем виртуальной памяти составляет 4 ГБ, и Linux, и Windows обычно резервируют последний 1 ГБ для ядра, что дает вам максимум 3 ГБ адресного пространства. Существует специальная версия Linux, которая ничего не резервирует, предоставляя вам полный 4GiB. Это полезно в редких случаях больших баз данных, где последний 1 ГБ экономит день, но при регулярном использовании он немного медленнее из-за дополнительных перезагрузок таблицы страниц.
На 64-битных платформах виртуальная память составляет 64EiB, и вам не нужно об этом думать.
Физическая память
Физическая память обычно выделяется операционной системой только тогда, когда процессу требуется доступ к ней. Сколько физической памяти использует процесс, очень нечеткое число, поскольку некоторая память распределяется между процессами (код, общие библиотеки и любые другие сопоставленные файлы), данные из файлов загружаются в память по требованию и удаляются при нехватке памяти и «анонимная» память (та, которая не поддерживается файлами) может быть заменена.
В Linux то, что происходит, когда у вас заканчивается физическая память, зависит от
vm.overcommit_memory
настроек системы. По умолчанию это overcommit. Когда вы просите систему выделить память, она отдает вам часть, а выделяет только виртуальную память. Когда вы на самом деле обращаетесь к памяти, она попытается использовать физическую память, отбрасывая данные, которые можно перечитать, или заменяя их по мере необходимости. Если он обнаружит, что не может ничего освободить, он просто удалит процесс из существования (нет способа реагировать, потому что для этой реакции может потребоваться больше памяти, и это приведет к бесконечному циклу).Вот как процессы умирают на Android (который также является Linux). Логика была улучшена с логикой, который процесс, чтобы удалить из существования на основе того, что процесс делает и сколько ему лет. Процессы Android просто перестают делать что-либо, но сидят на заднем плане, и «убийца нехватки памяти» убьет их, когда ему понадобится память для новых.
источник
Я думаю, что легче ответить на это по порядку использования памяти.
Вопрос 3: Как насчет текста (кода) и разделов данных, как они ограничены? Текст и данные подготовлены компилятором. Требование к компилятору - убедиться, что они доступны, и упаковать их в нижнюю часть адресного пространства. Доступное адресное пространство будет ограничено аппаратными средствами, например, если регистр указателя инструкций является 32-разрядным, то пространство текстового адреса будет равно 4 ГиБ.
Вопрос 2: Как определяется предел? Это общая доступная оперативная память? После текста и данных область над ней - это куча. С виртуальной памятью, куча может практически расти вверх близко к максимальному адресному пространству.
Вопрос 1: имеют ли стек и куча ограничение по статическому размеру (например, 2 гигабайта в каждом), или это ограничение динамическое, изменяющееся в соответствии с распределением памяти во время выполнения программы (т. Е. Всего 4 гигабайта, которые будут использоваться оба, так что, если программа использует только стек, она сможет иметь стек с 4 гигабайтами)? Последний сегмент в адресном пространстве процесса - это стек. Стек занимает конечный сегмент адресного пространства, он начинается с конца и уменьшается .
Поскольку куча растет и стек уменьшается, они в основном ограничивают друг друга. Кроме того, поскольку оба типа сегментов доступны для записи, один из них не всегда нарушает границы, поэтому вы можете переполнить буфер или стек. Теперь есть механизм, чтобы остановить их.
Для каждого процесса существует ограничение на кучу (стек). Этот лимит можно изменить во время выполнения (используя brk () / sbrk ()). В основном происходит, когда процессу требуется больше места в куче, и он исчерпал выделенное пространство, стандартная библиотека отправит вызов ОС. ОС будет выделять страницу, которая обычно будет управляться пользовательской библиотекой для использования программой. То есть, если программе требуется 1 КиБ, ОС выдаст дополнительные 4 КиБ, а библиотека предоставит программе 1 КиБ и оставит 3 КиБ для использования, когда в следующий раз программа запросит больше.
Большую часть времени макет будет Text, Data, Heap (растет), нераспределенное пространство и, наконец, Stack (растет). Все они имеют одинаковое адресное пространство.
источник