Как макет памяти используется совместно с другими процессами/потоками?

В настоящее время я изучаю структуру памяти в C. На данный момент я знаю, что в памяти программ C существует несколько разделов: text, data, bss, heap и stack. Они также говорят, что heap используется совместно с другими вещами вне программы.

Мои вопросы таковы.

  1. С чем именно делится heap? В одном источнике говорится, что куча всегда должна быть освобождена, чтобы сделать ее доступной для других процессов, тогда как в другом говорится, что область кучи совместно используется всеми потоками, общими библиотеками, и динамически загружаемые модули в процессе. Если он не используется совместно с другими процессами, действительно ли мне нужно освобождать его во время выполнения моей программы (а не в конце)?
  2. Некоторые источники также выделяют старшие адреса (шестой раздел) для аргументов командной строки и переменных среды. Считать ли это еще одним слоем и частью программной памяти?
  3. Доступны ли другие разделы для чего-либо помимо программы?

person Kaiyakha    schedule 03.12.2020    source источник
comment
На тему «Я знаю, что в памяти программы C существует несколько разделов: text, data, bss, heap и stack»: в каком документе говорится, что существует раздел с именем «куча»?   -  person Eric Postpischil    schedule 03.12.2020
comment
@EricPostpischil тогда назовите это pool, или что вы имеете в виду?   -  person Kaiyakha    schedule 03.12.2020
comment
У каждого процесса есть своя куча, сопоставленная с виртуализированными фрагментами памяти, запрашиваемыми у ОС. Было бы довольно странно, если бы вы могли получить доступ к куче других процессов из своей программы. Он также обычно освобождается после того, как существует только ваш процесс. Теоретически ваш диспетчер памяти C может вернуть часть памяти раньше, но, поскольку память обычно виртуализируется операционной системой, это просто усложняет ситуацию, не принося реальной пользы.   -  person Groo    schedule 03.12.2020
comment
@Kaiyakha: Я хотел бы знать, в каком документе это сказано. Это был учебник? Спецификация Unix? Страница руководства? Есть ли у него название, автор, дата публикации, версия?   -  person Eric Postpischil    schedule 03.12.2020
comment
@EricPostpischil все, что я могу сделать, это просто процитировать TAOCP p. 435: Примерно в 1975 году несколько авторов стали называть пул доступной памяти кучей. Но в этой серии книг мы будем использовать это слово только в его более традиционном смысле, связанном с очередями с приоритетом. Я понятия не имею, откуда оно взялось, но в настоящее время оно, похоже, довольно широко распространено.   -  person Kaiyakha    schedule 03.12.2020


Ответы (3)


  1. heap — это память для каждого процесса: каждый процесс имеет свою собственную кучу, которая совместно используется только в пределах одного и того же пространства процесса (например, между потоками процесса). em>, как вы сказали). Почему вы должны освободить его? Не совсем для того, чтобы дать место другим процессам (по крайней мере, в современной ОС, где память процесса освобождается ОС, когда процесс умирает), но для предотвращения исчерпания кучи в памяти вашего процесса: в C, если вы не освобождаете кучу области памяти, которые вы использовали, они всегда будут считаться занятыми, даже если они больше не используются. Таким образом, для предотвращения нежелательных ошибок рекомендуется освобождать память в куче, как только она вам больше не нужна.
  2. В программе C переменные командной строки хранятся в стеке как функциональные переменные main. Что происходит, так это то, что стек обычно размещается в верхней части памяти процесса, которая отображается на старшие адреса (вероятно, это причина, по которой некоторые источники указывают на то, что вы написали). Но, вообще говоря, никакой шестой области памяти нет.
  3. Как сказали другие, область text может совместно использоваться процессами. Эта область обычно содержит двоичный код, который будет одинаковым для разных процессов, использующих один и тот же двоичный код. По соображениям производительности ОС может разрешить совместное использование такой области памяти (подумайте, например, когда вы fork дочерний процесс).
person Pasquale    schedule 03.12.2020
comment
А остальные слои не разделяются даже между потоками одного и того же процесса, верно? - person Kaiyakha; 03.12.2020
comment
Потоки разделяют все, кроме stack: каждый поток имеет свой собственный стек (даже несмотря на то, что стеки разных потоков помещаются в один и тот же стек процесса, часто рядом). Но поток не может получить доступ к стеку родственного потока, иначе возникнет исключение памяти. - person Pasquale; 03.12.2020

  1. Куча используется совместно с другими процессами в том смысле, что все процессы используют оперативную память. Чем больше вы используете, тем меньше доступно другим программам. Совместное использование кучи с другими потоками в вашей собственной программе означает, что все ваши потоки на самом деле видят и получают доступ к одной и той же куче (одно и то же виртуальное адресное пространство, одна и та же фактическая оперативная память, а если повезет, и один и тот же кеш).
  2. No.
  3. text можно использовать совместно с другими процессами. В наши дни он помечен как доступный только для чтения, поэтому имеет смысл иметь несколько процессов, совместно использующих text. На практике это означает, что если вы уже запускаете top и запускаете другой экземпляр, нет смысла снова загружать text часть. Это приведет к пустой трате времени и физической оперативной памяти. Если ОС достаточно умна, она может отображать эти страницы ОЗУ в виртуальное адресное пространство обоих экземпляров top, экономя время и пространство.
person TCvD    schedule 03.12.2020
comment
Что здесь top? - person Kaiyakha; 03.12.2020
comment
Инструмент Linux, который показывает текущее использование ЦП, запущенные процессы и т. д. Просто пример процесса, который выполняется какое-то время. Хотите попроще? Как насчет sleep? - person TCvD; 03.12.2020
comment
Я просто не пользователь Linux :) Под processes я имел в виду любую другую запущенную программу, не так ли? - person Kaiyakha; 03.12.2020
comment
Не проблема. Допустим, в Windows вы смотрите два фильма одновременно с помощью VLC. Это означает, что vlc.exe нужно разместить в оперативной памяти только один раз. - person TCvD; 03.12.2020
comment
Теперь ясно. И последний вопрос! Если heap используется совместно с другими программами, может ли он быть таким же большим, как вся оперативная память (или близко к этому)? - person Kaiyakha; 03.12.2020
comment
Будьте осторожны здесь. Для большинства этот оператор означает, что одна программа имеет доступ к heap другой программы. Это не вариант. Как я уже сказал, все они совместно используют ОЗУ, а это означает, что в один момент процесс 1 может занимать страницу ОЗУ, а в следующий момент эту страницу может занимать другой процесс. - person TCvD; 03.12.2020
comment
heap на самом деле может быть больше, чем физическая оперативная память из-за магии подкачки, но это замедлит работу вашей машины. - person TCvD; 03.12.2020
comment
То есть практически у каждого процесса есть своя куча, и они не используют одну и ту же кучу? - person Kaiyakha; 03.12.2020
comment
Верный. Если бы они это сделали, это было бы проблемой безопасности. - person TCvD; 03.12.2020
comment
Тогда не только Heap используется совместно с другими процессами в том смысле, что все процессы используют оперативную память, но и другие уровни, не так ли? Они же используют ту же оперативную память, не так ли? - person Kaiyakha; 03.12.2020
comment
Они делают. В итоге все в ОЗУ. Однако допустим, что у вас либо нет свопа, либо вы достигли его предела. В этом случае вы не можете получить больше кучи. Если подкачка уже полностью использована, вы не можете ничего выгрузить из ОЗУ, сделать файл подкачки, поэтому для вас больше не будет кучи (или стека). Тем не менее, вы можете в основном выбросить исполняемый код из оперативной памяти. Если вам это нужно, вы всегда можете перезагрузить его из исполняемого файла, из которого он был получен в первую очередь. - person TCvD; 03.12.2020

Официально:

Термины поток, процесс, текстовый раздел, раздел данных, bss, < em>куча и стек даже не определены стандартом языка C, и каждая платформа может свободно реализовывать эти компоненты по своему усмотрению.

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

Что касается практического аспекта:

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

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

Обычно это достигается с помощью утилит синхронизации, таких как семафоры, мьютексы и очереди сообщений.

В промежутках между процессами операционная система отвечает за обеспечение взаимного исключения.

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

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

person goodvibration    schedule 03.12.2020