Существует ли распределитель STL, который не будет неявно освобождать память?

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

Мой идеальный распределитель никогда не освобождал бы память неявно, и на самом деле вполне приемлемо, если бы память освобождалась только при уничтожении распределителя. Функция-член для явного освобождения неиспользуемой памяти была бы хорошей, но не обязательной. Я знаю, что то, о чем я говорю, звучит как распределитель для каждого объекта, и это нарушает стандарт. Я бы предпочел придерживаться стандарта, но откажусь от него, если не смогу решить это в нем.

Меня меньше интересует начальная производительность и больше средняя производительность. Иными словами, не так важно, выделяется ли отдельный элемент или их пул за раз, и важнее, приводит ли указанное выделение к вызову new/malloc. У меня нет проблем с написанием собственного распределителя, но кто-нибудь знает уже существующий, который выполняет это? Если это имеет значение, это будет для смежных контейнеров памяти (например, вектор, дек), хотя обобщенное решение было бы неплохо.


person jorgander    schedule 06.10.2011    source источник
comment
Распределитель STL по умолчанию держит довольно хороший кусок памяти на всякий случай. Вы уверены, что этого недостаточно?   -  person Matthieu M.    schedule 06.10.2011
comment
deque не является непрерывным контейнером памяти.   -  person Fred Larson    schedule 06.10.2011
comment
Я бы хотел, чтобы распределитель, если это возможно, был полезен как для больших, так и для малых контейнеров, поэтому хранение большого количества дополнительной памяти (особенно для каждого объекта) может быть слишком расточительным? Это может показаться противоречащим тому, что я сказал о невысвобождении памяти, но идея в том, что память должна быть запрошена, а не выделена на всякий случай.   -  person jorgander    schedule 06.10.2011
comment
Правильно насчет deque - это не гарантирует смежных элементов. Я почти никогда не использовал его, но помню, что он поддерживал произвольный доступ по индексу позиции.   -  person jorgander    schedule 06.10.2011
comment
@bdonlan: std::deque требуется для обеспечения [амортизированного] произвольного доступа с постоянным временем   -  person Dennis Zickefoose    schedule 11.10.2011
comment
@DennisZickefoose, ах, ты действительно прав   -  person bdonlan    schedule 11.10.2011


Ответы (1)


Я надеюсь, что это не слишком просто.

Памяти будет выделено и освобождено больше для добавления элементов, чем для их удаления.

Я считаю, что «освобождение» памяти невозможно, если вы не знаете максимальное количество элементов, разрешенных вашим приложением. CRT может попытаться выделить больший блок памяти на месте, но как вы поступите в случае сбоя?

Объяснение:

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

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

  • В С++ 11 и TR1 у вас может быть идеальная переадресация, когда нужно копировать только указатель на элементы. Это делается с помощью конструктора перемещения вместо конструктора копирования.

Однако вы, похоже, хотите максимально избежать перераспределения.

Используя распределитель по умолчанию для вектора, вы можете указать начальную емкость.

  • Емкость — это выделенная память, а размер — количество элементов.

  • Память будет выделяться только при построении и если размер достигает емкости. Это должно происходить только с push_back();

  • Распределитель по умолчанию увеличивает емкость в несколько раз (например, в 1,5, 2,0), чтобы перераспределение происходило за линейное время. Итак, если у вас есть цикл, который отталкивает данные, он линейный. Или, если вы знаете количество элементов заранее, вы можете выделить один раз.

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

Если вы все еще хотите написать свой собственный распределитель, это хорошая статья.

настраиваемые распределители

person Ben L    schedule 10.10.2011