Какие области памяти, помимо стека и кучи, существуют в iOS/macOS?

Ответ

Помимо стека (для локальных переменных и вызовов функций) и кучи (для динамически выделяемых объектов), в процессах существуют и другие сегменты памяти:

  1. Сегмент кода (Text/Code Segment):

    • Содержит: Исполняемый машинный код программы (инструкции).
    • Особенности: Только для чтения (read-only), защищен от модификации.
  2. Сегмент данных (Data Segment):

    • Глобальные и статические данные (Global/Static): Хранит статические переменные (static), глобальные переменные и константы, инициализированные при запуске. Существует всю жизнь процесса.
      static let appVersion = "1.0.0" // Хранится здесь
    • BSS (Block Started by Symbol): Подсекция для неинициализированных глобальных и статических переменных (заполняется нулями).
  3. Регистры процессора (Registers):

    • Сверхбыстрая память внутри CPU для временных данных и адресов во время исполнения инструкций. Не адресуется напрямую в коде.
  4. Memory-mapped I/O:

    • Специальная область, где адреса памяти соответствуют не ОЗУ, а регистрам аппаратных устройств. Чтение/запись по этим адресам управляет железом.
  5. Thread-local Storage (TLS):

    • Память, уникальная для каждого потока. В Swift доступ через Thread.current.threadDictionary.
      Thread.current.threadDictionary["requestId"] = "123"
  6. Autorelease Pool:

    • Не является отдельной физической областью, но это важный механизм управления временем жизни объектов. В него попадают объекты, от которых отказались с помощью autorelease (в Objective-C/Swift с @autoreleasepool). Пул периодически дренируется, освобождая объекты.

Важно: ARC в Swift управляет памятью объектов в куче. Стек используется для примитивов, структур и ссылок на объекты. Глобальные константы (let) могут размещаться в сегменте данных или (для оптимизации) непосредственно в коде.

Ответ 18+ 🔞

Да ты посмотри, какая у нас тут картина маслом, блядь! Помимо этого цирка со стеком и кучей, где у нас локальные переменные пляшут, а объекты в динамике выделяются, в каждом процессе творится ещё целая опера, сука! Целый театр сегментов памяти, ёпта!

Ну, сегмент кода, его ещё text segment зовут. Это типа священное писание твоей программы, блядь. Там лежит весь машинный код, инструкции, что процессор жуёт. И трогать его низя! Только читать. Защищённый, блядь, как банковский сейф. Попробуй туда что-то записать — получишь segmentation fault прямо в ебало.

Дальше — сегмент данных. О, это уже интереснее. Тут два зала, как в борделе. Первый зал — для понтовых, инициализированных при старте. Глобальные переменные, статические константы — вся эта шушера, которая живёт от рождения процесса до самой смерти.

static let appVersion = "1.0.0" // Вот эта красавица — тут и сидит, блядь.

А второй зал — BSS. Это типа подсобка для лентяев. Сюда складывают глобальные и статические переменные, которые нихуя не инициализировали. При запуске их просто нулями забивают, и всё. Экономят место в исполняемом файле, хитрожопые.

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

Memory-mapped I/O — это вообще магия, блядь. Ты пишешь в какую-то, блядь, ячейку памяти, а на самом деле ты не в память пишешь, а в регистр видеокарты какой-нибудь или сетевухи! Адреса эти — липа полная, за ними железо прячется. Настоящий фокус-покус.

Thread-local Storage (TLS) — это когда каждому потоку своя хата, свои личные вещички. Чтобы не путались, сволочи. В Swift это через Thread.current.threadDictionary делается.

Thread.current.threadDictionary["requestId"] = "123" // Каждый поток со своим requestId, никакой путаницы, блядь.

Ну и autorelease pool, ёбана! Это не место, а состояние души, блядь. Механизм такой. В Objective-C (и в Swift через @autoreleasepool) объекты, от которых отказались, не сразу на свалку летят, а в этот пул попадают. А потом пул дренируют — и всё, пиздец объектам, освобождаются. Удобно для временщиков.

Самое главное, на чём мозг сломать можно: ARC в Swift — это про кучу, про объекты. Стек — для примитивов, структур и ссылок. А глобальные константы (let) — те вообще могут где угодно оказаться: или в сегменте данных, или прямо в коде вшиты, если компилятору так захотелось. Вот такая, блядь, архитектурная многоэтажка получается, в рот меня чих-пых!