boost fast_pool_allocator иногда запрашивает огромное выделение

У меня есть многопоточное приложение, которое использует fast_pool_allocator boost (версия 1.55) под быстрая починка (1.13.3). Приложение распределяет большое количество объектов в течение дня, увеличиваясь более или менее линейно до тех пор, пока мы не выключим его, используя к концу дня порядка 32 ГБ виртуальной памяти. Большинство выделенных ресурсов составляют порядка 200 МБ, так как мы наблюдаем рост виртуальной памяти приложения. Но затем, в какой-то момент, обычно позже в тот же день, boost решает выделить 6 ГБ, хотя поток транзакций через приложение существенно не меняется.

Глядя на код распределителя, первое, что делает повышение, после распределения нового блока на блоки. Функция simple_segregated_storage<SizeType>::segregate at simple_segregated_storage.hpp: 280. Мы подключили к процессу отладчик и заметили, что когда происходит гигантское распределение, выполнение этой функции (что неудивительно) занимает много времени, в частности цикл for в строке 302. Это занимает 20-30 секунд, и этот код защищен мьютексом, поэтому каждый другой поток пытается что-то сделать в блоках распределителя. Это злит наших клиентов.

Вопросы:

  1. Зачем ему вдруг выделять 6 ГБ, когда он постоянно просил ~ 200 МБ блоков весь день до этого?
  2. Можно ли как-то ограничить распределение? Я бы предпочел, чтобы он попросил меньшие кусочки чаще.
  3. Это неправильный распределитель? Я полагаю, что это вопрос для разработчиков быстрых исправлений, но, похоже, это их предпочтительный путь. Объекты, которые используют распределитель, в основном std::map а также std::multimap,

2

Решение

Как предложено выше Yakk, оказывается, что пул наддува позволяет вам указать MaxSize в шаблоне. Немного странно, что он работает в единицах «порций», концепции, внутренней для реализации пула. ИМХО байты были бы более естественными, но так и будет.

fast_pool_allocator определяется значениями по умолчанию для всех аргументов шаблона (кроме первого). Я скопировал эти значения по умолчанию и изменил последний. Для этого приложения размер фрагмента составляет 88 байтов, но я предполагаю, что это зависит от класса на карте.

typedef std::map <int, std::vector <FieldMap*>, std::less<int>,
boost::fast_pool_allocator<std::pair<const int, std::vector<FieldMap*>>,
boost::default_user_allocator_new_delete,
boost::details::pool::default_mutex,
32,       // NextSize (default from boost)
1500000   // MaxSize, in 88 byte chunks.
>> Groups;

В этом случае 1500000 * 88 = 132M, что примерно столько, сколько я хочу, чтобы распределение было на данный момент.

1

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


По вопросам рекламы ammmcru@yandex.ru
Adblock
detector