& quot; Фрагментация памяти & quot; это все еще проблема?

Я немного смущен. В ходе курса ОС нам сказали, что все ОС заботятся о фрагментации памяти путем разбиения на страницы или сегментации, и непрерывное выделение физической памяти вообще отсутствует. ОС использует разные уровни адресации (логическая / физическая), чтобы избежать непрерывного выделения памяти. Сейчас Вот Есть так много дискуссий по этому поводу. Мой вопрос:
Реальна ли эта проблема в программировании на С ++ для ОС, поддерживающих логическую адресацию (происходит ли сбой любого процесса только из-за фрагментации памяти)? если да, то почему в первую очередь каждая ОС пытается избежать смежной адресации?

6

Решение

Существует два уровня: фрагментация в адресном пространстве виртуального процесса и фрагментация в физической памяти.

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

Если вас интересует фрагментация в физической памяти, то даже с памятью, организованной по страницам, все равно есть необходимость выделять физически смежные фрагменты памяти. Например, если вам нужно избежать накладных расходов виртуальной памяти, вы можете использовать большие страницы («огромные страницы» в терминах Linux). x86_64 поддерживает страницы 4 КБ, 2 МБ и 1 ГБ. Если нет смежных физическое памяти нужного размера, вы не сможете их использовать.

Если под ОС вы подразумеваете «ядро», то это не поможет вам с фрагментацией, которая происходит в адресном пространстве процесса (фрагментация кучи). Библиотека C должна стараться избегать фрагментации, к сожалению, это не всегда удается сделать. Смотрите ссылку вопрос.

Распределитель памяти обычно не может освободить большой кусок памяти, если в нем есть хотя бы что-то выделенное. Это частичное решение, которое использует преимущества организации виртуальной памяти на страницах — так называемый механизм «без лени», представленный MADV_FREE на Linux и BSD и DiscardVirtualMemory на винде. Если у вас огромный кусок памяти, который используется только частично, вы можете уведомить ядро ​​о том, что часть этой памяти больше не нужна и что она может вернуть ее обратно под давлением памяти. Это делается лениво и только под давлением памяти, потому что освобождение памяти чрезвычайно дорого. Но многие распределители памяти все еще не используют его по соображениям производительности.

Так что ответ на ваш вопрос — это зависит от того, насколько вы заботитесь об эффективности вашей программы. Большинству программ пофиг, так как стандартный распределитель просто выполняет за них работу. Некоторые программы могут страдать, когда стандартный распределитель не может эффективно выполнять свою работу.

6

Другие решения

ОС не избегает непрерывного выделения памяти. На верхнем уровне у вас есть аппаратное и программное обеспечение. Аппаратные средства имеют ограниченные ресурсы, в данном случае физическую память. Чтобы поделиться ресурсом и избежать того, чтобы пользовательские программы позаботились о его совместном использовании, был изобретен слой виртуальной адресации. Он просто отображает смежное виртуальное адресное пространство в редкие физические области. Другими словами, виртуальный адрес 0x10000 может указывать на физический адрес 0x80000 в одном процессе и на 0xf0000 в другом.

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

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

Теперь второй уровень фрагментации, который вызван new/malloc функций, и это связано с тем, что вы выделяете и удаляете разные размеры памяти. Это фрагментирует вашу кучу в виртуальном пространстве. Функции обеспечивают минимальное количество отходов.

Таким образом, при программировании на C ++ (или на любом другом языке) вас не волнует фрагментация памяти. Все фрагменты, которые вы выделяете, гарантированно будут смежными в виртуальном пространстве (не обязательно в физическом).

3

По вопросам рекламы [email protected]