Совместное использование библиотек и исполняемых файлов со статической средой выполнения C в Linux. У каждого из них отдельная куча как у винды?

0

Я понимаю, как распределить кучу окна и стек кучи и т.д. Хотя я новичок в Linux, у меня нет большей ясности, как это работает?

В Windows:

  1. В начале процесса ОС создает кучу по умолчанию, называемую Process heap. Куча процесса используется для выделения блоков, если не используется другая куча.
  2. Время выполнения языка также может создавать отдельные кучи внутри процесса. (Например, время выполнения C создает кучу.)
  3. Помимо этих выделенных куч, прикладная программа или одна из многих загруженных библиотек динамической компоновки (DLL) могут создавать и использовать отдельные кучи, называемые частными кучами
  4. Эта куча находится поверх операционной системы Virtual Memory Manager во всех системах виртуальной памяти.
  5. a) C/C++ Распределитель времени выполнения (CRT): предоставляет команды malloc() и free(), а также новые и удаленные операторы. b) CRT создает такую дополнительную кучу для всех ее распределений (дескриптор этой кучи CRT хранится внутри библиотеки CRT в глобальной переменной, называемой _crtheap) как часть ее инициализации. c) CRT создает свою собственную кучу, которая находится поверх кучи Windows. d) Куча Windows - это тонкий слой, окружающий диспетчер времени выполнения Windows (NTDLL). e) Распределитель времени выполнения Windows взаимодействует с Virtual Memory Allocator, который резервирует и фиксирует страницы, используемые ОС.

Наши библиотеки DLL и exe ссылаются на многопоточные статические библиотеки CRT. Каждая DLL и exe, которую мы создаем, имеют свою собственную кучу, то есть _crtheap. Выделения и отчисления должны произойти из соответствующей кучи. То, что динамически выделяется из DLL, не может быть выделено из исполняемого файла и наоборот.

Компиляция нашего кода в DLL и exes с использованием /MD или /MDd для использования многопоточной и DLL-специфичной версии библиотеки времени выполнения свяжет как DLL, так и exe с той же библиотекой времени выполнения C и, следовательно, с одним _crtheap. Выделения всегда сопряжены с де-распределениями в одном модуле.

Это то же самое поведение на Liunx? Какие там кучи? Что относительно кучи CRT?

Теги:
memory-management
crt

1 ответ

1

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

Как человек unix, то, что я узнал об управлении памятью Windows из вашего вопроса, заключается в том, что вы, ребята, много используете слово "куча". Мы этого не делаем, кроме как неофициальный синоним для "области памяти, управляемой malloc".

Есть два основных динамических элемента распределения памяти, о которых нужно знать: brk и mmap. Все остальные функции распределения, включая malloc, строятся поверх них.

brk - старый. Он работает, просто добавляя больше памяти к карте виртуальной памяти процесса после окончания сегмента bss. Вы передаете значение " brk, и это становится "разрывом" процесса - окончанием выделенной виртуальной памяти.

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

См. Также: Что делает системный вызов brk()? (у него есть фотографии!)

Это действительно необычно для программы, чтобы напрямую вызвать brk. (Или даже тонкую обертку sbrk). Каждое использование brk в обычной программе осуществляется через malloc. Помните, что хотя вы просматриваете библиотеку C, в том числе malloc, как дополнительную опцию, у нас есть OS, которая тесно связана с C, поэтому программа, которая не использует libc для низкоуровневых материалов, таких как управление памятью, очень Действительно. Поэтому большую часть времени все память в сегменте brk, ака "куча" управляется malloc. Однако обратное неверно, потому что...

mmap, новее, чем brk (mmap с 90-х годов, brk - с 70-х годов) предлагает множество вариантов. Если вы хотите отобразить файл в память или выделить несколько несмежных блоков памяти вместо того, чтобы просто добавить некоторое пространство в конце исходного блока данных, вы используете mmap. Погружаемый библиотечный загрузчик использует mmap для сопоставления каждого текста библиотеки и данных. Современные реализации malloc используют mmap для больших запросов и brk для небольших. У нас также есть mremap который переносит сопоставление на новый виртуальный адрес, сохраняя при этом один и тот же физический адрес, позволяя realloc избежать дорогостоящей копии.

Если вы посмотрите на /proc/$PID/maps в Linux, вы увидите область памяти с надписью [heap]. Это сегмент brk. Там только один из этих процессов. (Я видел несколько примеров, в которых файл maps показывал 2 из них, но они были непрерывными и имели одинаковые атрибуты, поэтому они действительно эквивалентны одному региону. Я не знаю, что вызывает двойной листинг.)

С учетом всего этого, что бы это значило, чтобы выделить "лишнюю кучу"? Вы можете запросить некоторую память из системы с помощью mmap, предоставив вам регион, который не зависит от malloc. Затем вы можете сделать свое собственное malloc-подобное управление этим регионом, раздавая его кусками разных размеров и отслеживая, какие части не используются. Но ваш новый распределитель не будет "кучей". Что на самом деле ничего не значит, потому что система ничего не знает о кучах.

  • 0
    Спасибо, шутки, за понимание. Что происходит, когда разделяемая библиотека, которая статически связана с libc, загружается исполняемым файлом, который также статически связывается с libc. Будет ли тогда две кучи? Если да, память выделяется из одного и освобождается от другого, будет ли проблема?
  • 0
    Я не знаю ... статическое связывание не всегда хорошо поддерживается, и я думаю, что если вы зашли так далеко, что в итоге вы получили 2 копии одной и той же библиотеки, связанной с вашим работающим кодом, вы допустили серьезную стратегическую ошибку.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню