Как увеличение размера каждой памяти на фиксированное число байтов повлияет на фрагментацию кучи? - PullRequest
3 голосов
/ 10 декабря 2010

Я заменил operator new() в моей программе на C ++, поэтому выделяет немного больший блок для хранения дополнительных данных .Таким образом, программа выполняет точно такой же набор выделений, за исключением того, что теперь она запрашивает на несколько байтов больше памяти при каждом выделении.В противном случае его поведение полностью совпадает, и он обрабатывает точно такие же данные.Программа выделяет множество блоков (я полагаю, миллионов) разных размеров во время выполнения.

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

Ответы [ 4 ]

2 голосов
/ 10 декабря 2010

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

Думая об обратном, представьте, что ваша программа изначально использовала блоки таких же размеров, что и блок с модифицированным распределителем. В таком случае не беспокоитесь о фрагментации памяти?

1 голос
/ 10 декабря 2010

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

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

В зависимости от ваших потребностей в использовании памяти, вам может быть лучше использовать собственный аллакатор для замены ::new, что-то вроде hoard или nedmalloc.

1 голос
/ 10 декабря 2010

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

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

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

1 голос
/ 10 декабря 2010

Если ваши блоки (выделенная и освобожденная память) все еще меньше, чем распределитель библиотеки C обрабатывает без проблем с фрагментацией, вы не должны сталкиваться с какой-либо фрагментацией памяти. Например, посмотрите на мой собственный вопрос о распределителях: Распределитель небольших блоков в Linux (или RedHat Linux), чтобы избежать фрагментации памяти .

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...