Ответ 1
Современные операционные системы не дают вам прямого доступа к аппаратной ОЗУ и вместо этого абстрактно его в так называемую виртуальную память, которая по требованию сопоставляется с ОЗУ. Каждому процессу обычно предоставляется собственная личная копия полного адресного пространства. Это позволяет ОС перемещать память процесса в ОЗУ во время выполнения или даже заменять его на диск. Это происходит прозрачно, то есть процесс не уведомляется о таком перемещении и не нуждается в коде для его обработки. (В некоторых приложениях реального времени могут быть использованы методы, позволяющие предотвратить их замену памяти).
При связывании объектных файлов с исполняемым файлом или динамической библиотекой компоновщик статически выделяет память для инструкций процессора функции/метода и для всех глобальных переменных. Когда os загружает исполняемую или динамическую библиотеку, она отображает эту предварительно выделенную память в реальную память.
При запуске каждый поток получает частную область памяти, называемую стеком. Каждый раз, когда вы вызываете функцию/метод, компилятор вводит код для автоматического выделения (путем увеличения указателя стека) достаточного количества памяти из стека для хранения всех параметров, локальных переменных и возвращаемого значения (если есть), используемого функцией/методом. Если компилятор определяет, что достаточно оставить некоторые переменные в регистрах процессоров, он не выделяет для него память в стеке. Когда функция/метод возвращается, она запускает код, сгенерированный компилятором, чтобы освободить (уменьшив указатель стека) эту память. Обратите внимание, что деструкторы любых объектов в стеке будут вызываться, когда блок, который они определены в выходах, которые могут быть долгое время перед возвратом. Кроме того, компилятор может повторно использовать запатентованную память по своему усмотрению.
Когда генерируется исключение, компилятор компилятора вставляет специальный код, который знает макет стека и который может размотать его, пока не найдет подходящий обработчик исключений.
В отличие от этого, память в куче выделяется с помощью new
/delete
, для которой компилятор вставляет код для запроса или выпуска памяти с использованием системной библиотеки.
Обратите внимание, что это упрощенное описание, чтобы дать вам представление о том, как работает распределение памяти.