2016-05-12 4 views
10

Когда я использую malloc() s и free() s случайным образом, вложенным и с различными размерами, в какой-то момент память будет фрагментирована, поскольку эти операции оставляют большой список небольших областей памяти позади, которые являются несмежными и, следовательно, t быть выделен как одна большая часть.Фрагментация памяти

Несколько вопросов по этому поводу:

  • Когда это делается довольно часто, так что память вынуждена быть фрагментирован, а затем все эти области памяти являются free() d, Могу ли я считать, эти свободные районы конкатенация назад к ее первоначальному, смежному размеру?

  • Когда я всегда делаю malloc(), а затем free() для той же памяти и никогда не гнездю эти вызовы. Разве фрагментация памяти в этом сценарии тоже при распределенных/освобожденных размерах всегда различна?

+6

Все это зависит от реализации. Но, да, хороший менеджер памяти объединит смежные части свободной памяти. И да, если вы делаете 'malloc', за которым следует' free', и вы не вызываете никаких библиотечных функций, которые вызывают «malloc» между ними, тогда не должно произойти фрагментация. –

+2

Вы можете запустить Valgrind с вашей программой http://www.valgrind.org и проверить ошибки выравнивания данных и утечки памяти. –

+0

Трудно фрагментировать 64-разрядное адресное пространство. Конечно, вы можете легко фрагментировать его до такой степени, что вы больше не можете выделить объект с 10 ТБ, но, вероятно, у вас, по-видимому, не было 10-бит RAM. – MSalters

ответ

2

В соответствии с ИСО/МЭК 9899: 201x -> 7.22.3

Порядок и примыкания хранения выделяется последовательными вызовами aligned_alloc, calloc, таНос и функции перераспределить это не определено ,

Хороший менеджер памяти сможет решить проблему. Однако существуют и другие аспекты, такие как выравнивание данных [1], которое вызывает внутреннюю фрагментацию.

Что вы могли бы сделать, если полагаетесь на встроенное управление памятью?

  1. Используйте профайлер - скажем Valgrind - с возможностью проверки памяти, чтобы найти память, которая не освобождается после использования. Пример:

    valgrind --leak-check=yes myprog arg1 arg2 
    
  2. Следуйте передовую практику.Пример. В C++, если вы намерены другим наследовать свой полиморфный класс, вы можете объявить его деструктором виртуальным.

  3. Использование умных указателей.

Примечания:

  1. Internal fragmentation.

  2. Если вы хотите использовать собственную систему управления памятью, вы можете рассмотреть сборщик мусора Boehm-Demers-Weiser.

  3. Valgrind Инструментарий.

  4. Память, не освобожденная после использования, будет способствовать фрагментации.
5

Нет, не существует гарантий. В соответствии с N1570, 7.22.3 Memory management functions:

Порядок и примыкания хранения, выделенного последовательными вызовами aligned_alloc, calloc, таНос и функции перераспределить является не определено.

Во всяком случае, у вас есть два варианта на выбор:

  1. Полностью доверяю библиотечные функции управления памятью.
  2. Напишите свои собственные менеджеры памяти, если вы действительно уверены.

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

+0

На самом деле, поскольку вопрос (также) с тегами C++, две возможности не являются взаимоисключающими. Вы можете переопределить 'operator new' в классе по классу. – MSalters

Смежные вопросы