FAQ FreeBSD - Использование памяти

ОГЛАВЛЕНИЕ

12. Использование памяти 

12.1. Почему FreeBSD использует гораздо больше места в разделе подкачки, чем Linux?

Это только кажется, что для FreeBSD требуется больше места на разделе подкачки,
чем для Linux. На самом деле это не так. Главное отличие FreeBSD от Linux в
этом плане заключается в том, что FreeBSD активно перемещает неиспользуемые
страницы памяти, к которым не было обращений, в раздел подкачки, чтобы ув
еличить объём доступной физической памяти для активного использования. Linux же
перемещает страницы памяти в раздел подкачки только в крайнем случае.
Получаемое во FreeBSD увеличение нагрузки на раздел подкачки компенсируется
более эффективным использованием оперативной памяти.
Заметьте, что, хотя FreeBSD предпочитает использовать раздел подкачки, она не
может сбросить все неактивные страницы в своп при полностью неактивной системе.
Так что вряд ли может возникнуть ситуация, когда, проснувшись рано утром, вы
обнаружите, что вся ваша система находится в разделе подкачки, хотя она простаи
вала всю ночь.

12.2. Почему утилита top(1) показывает очень маленький объём свободной памяти, даже когда запущено всего лишь несколько приложений?

Просто дело в том, что под свободной памятью подразумевается никак не
используемая память. Вся память, которая вашей программе явно не выделялась,
используется ядром FreeBSD для дискового кэша. Значения, показываемые утилитой
top(1), помеченные как Inact, Cache и Buf - это всё кэшированные данные разных
степеней устаревания. То, что данные находятся в кэше, означает, что система не
будет обращаться к медленному диску снова за теми данными, обращение к которым
было недавно, повышая таким образом общую производительность. В общем случае
маленькие значения в пункте Free, показываемые утилитой top(1) для свободной
памяти - это хорошо, если, конечно они не очень маленькие.

12.3. Почему используются (и что из себя представляют) форматы выполнимых файлов a.aut и ELF?

Для понимания того, почему FreeBSD использует формат ELF, вы должны сначала
получить представление о трёх "доминирующих" форматах выполнимых файлов для
UNIX:
    Note: До FreeBSD версии 3.x, во FreeBSD использовался формат a.out.
  * a.out
    Это самый старый, "классический" формат объектных файлов для UNIX. В нём
    используется короткий и компактный заголовок с магическим числом в начале,
    которое часто используется для определения формата (за подробным описанием
    обратитесь к странице Справочника о a.out(5)). Он содержит три загружаемых
    сегмента: .text, .data и .bss плюс таблицу символов и таблицу строк.
  * COFF
    Это формат объектных файлов SVR3. Дополнительно в заголовок включена
    таблица секций, так что вы можете иметь их больше, чем только .text, .data
    и .bss.
  * ELF
    Преемник COFF, в который добавлены возможности иметь много секций и 32- или
    64-разрядные значения. Один большой минус: ELF был спроектирован также в
    предположении, что для каждой аппаратной платформы будет существовать
    только один ABI. Это предположение достаточно некорректно, и даже в мире
    коммерческих реализаций SYSV (в котором имеется по крайней мере три ABI:
    SVR4, Solaris и SCO) это не так.
    FreeBSD каким-то образом пытается решить эту проблему, предоставляя утилиту
    для пометки конкретного выполнимого файла ELF с информацией о ABI, с
    которым он совместим. Обратитесь к странице Справочника об утилите brandelf
    за подробной информацией.

FreeBSD выросла на "классических" традициях и традиционно использовала формат
a.out, технологию, опробованную и проверенную во многих вариациях BSD. Хотя дав
но уже можно было компилировать и выполнять родные выполнимые файлы (и ядро) в
формате ELF, FreeBSD с самого начала сопротивлялась переходу на ELF как на
формат, используемый по умолчанию. Почему? Когда мир Linux делал болезненный
переход к ELF, причин отвергнуть формат a.out было не так уж и много, разве что
их негибкий механизм работы с совместно используемыми библиотеками, который был
основан на таблице переходов, что делало построение таких библиотек очень
затруднительным для разработчиков. Так как средства работы с ELF предоставляли
решение этой проблемы и это было в общем-то "шагом вперёд" в любом случае, цена
перехода была признана стоящей того и переход был сделан.
В случае FreeBSD, наш механизм работы с совместно используемыми библиотеками
очень похож на механизм, применяемый в SunOS, поэтому его очень легко использов
ать. Однако, начиная с 3.0, FreeBSD официально поддерживает ELF как формат,
используемый по умолчанию. И, хотя формат a.out поддерживается в полной мере,
разработчики из проекта GNU, являющиеся авторами компилятора, который мы
используем, больше не поддерживают формат a.out. Это заставило нас поддерживать
различные версии компилятора и компоновщика, и не позволило воспользоваться в
семи возможностями последних разработок GNU. Потребность в наличии реализации
ISO-C++, в основном конструкторов и деструкторов, также привела к поддержке ELF
в будущих релизах FreeBSD.

12.4. Да, но почему так много разных форматов?

Если вернуться в далёкое тёмное прошлое, то тогда компьютеры были очень просто
устроены. На них могла работать простая, маленькая система. Формат a.out
полностью решал задачу представления программ на простых системах (PDP-11).
Когда же люди перенесли unix с простых систем, они оставили a.out, так как его
было достаточно для ранних реализаций unix для таких архитектур, как Motorola
68k, VAX, и тд.
Затем какой-то умный инженер решил, что если он может заставить программное
обеспечение делать некоторые тонкие манипуляции, то это позволит преодолеть
некоторые ограничения при проектировании и позволит ядру процессора работать
быстрее. Когда это было сделано с новым типом аппаратуры (в наши дни известном
как RISC), оказалось, что a.out плохо подходит для этой аппаратуры, поэтому
было разработано много новых форматов для достижения большей производительности
от такого аппаратного обеспечения, чем может дать простой, имеющий ограничения
формат a.out. Были разработаны такие форматы, как COFF, ECOFF и ещё несколько
безвестных других со своими ограничениями, пока наконец все не остановились на
формате ELF.
Вдобавок к этому, так как размеры программ стали достигать огромных размеров, а
дисковая (и физическая) память оставалась сравнительно небольшой, то возникла
концепция совместно используемых библиотек. Система VM также стала более
мощной. Хотя каждое из этих нововведений продолжало использовать формат a.out,
его бесполезность становилась видна всё больше и больше с добавлением каждой но
вой возможности. К тому же люди захотели динамически загружать код во время в
ыполнения программ или сбрасывать части программ после выполнения кода
инициализации для экономии основной памяти и/или размера свопа. Языки
программирования становились всё более умными и люди захотели автоматического
запуска некоторого кода перед главной процедурой программы. С форматом a.out
была сделана масса ухищрений для реализации всех этих требований, и они в
общем-то работали. В конце концов наступил момент, когда формат a.out перестал
бы справляться со всеми этими проблемами без ещё больших потерь в коде и
гибкости в работе. Тогда как ELF решал многие из этих проблем, переход на него
был бы болезненным на рабочей системе. Так что ELF ждал момента, когда был бы
более болезненным оставаться с форматом a.out, чем перейти к формату ELF.
Однако с течением времени инструменты разработки, на которых основаны
инструменты разработки FreeBSD (особенно ассемблер и загрузчик), разделились на
две параллельные ветви. В дерево FreeBSD была добавлена поддержка совместно
используемых библиотеки и были исправлены некоторые ошибки. Разработчики из
GNU, которые изначально писали эти программы, полностью их переделали, добавив
более простую поддержку построения кросс-компиляторов, в котором можно использо
вать различные форматы, и тд. Когда многие захотели строить кросс-компилятор с
выходным кодом для FreeBSD, то им не повезло, так как старые исходные тексты,
которые FreeBSD использовала для as и ld, не подошли. Новый набор утилит от GNU
(binutils) поддерживает кросс-компиляцию, ELF, совместно используемые
библиотеки, расширения C++, и тд. Вдобавок, многие разработчики выпускают
программы в бинарном формате ELF, и для FreeBSD было бы полезно иметь в
озможность их запускать. И если такая возможность будет реализована, зачем
тогда вообще продолжать опираться на a.out? Это измученная старая лошадь,
которая была полезна долгое время, но сейчас самое время от неё отказаться,
оставив в прошлом долгие годы преданной службы.
ELF более выразителен, чем a.out, и позволяет реализовать большую расширяемость
основной системы. Инструменты для работы с ELF лучше поддерживаются
разработчиками, и предоставляют поддержку кросс-компиляции, что для многих в
ажно. ELF может работать немного медленнее, чем a.out, но это трудно измерить.
Также между ними есть некоторые отличия по распределению страниц памяти,
обработке кода инициализации, и тд. Никакие из этих отличий особо не важны, но
эти отличия всё же есть. Со временем поддержка a.out будет убрана из ядра
GENERIC, и постепенно убрана из системы совсем, как только отпадёт нужда в
запуске старых программ в формате a.out.