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