У меня есть многопоточное приложение, которое использует fast_pool_allocator (версия 1.55) под quickfix (1.13.3). Приложение выделяет большое количество объектов в течение дня, увеличиваясь более или менее линейно, пока мы не выключим его, используя порядка 32 ГБ виртуальной памяти к концу дня. Большинство распределений составляет порядка 200 МБ, поскольку мы наблюдаем рост объема виртуальной памяти приложения. Но затем, в какой-то момент, как правило, позже в тот же день, boost решает выделить 6 ГБ, хотя поток транзакций через приложение существенно не меняется.
Глядя на код распределителя, первое, что делает boost после распределения, устанавливает новый блок на куски. Функция simple_segregated_storage<SizeType>::segregate
по адресу simple_segregated_storage.hpp:280. Мы подключили к процессу отладчик и заметили, что когда происходит гигантское выделение памяти, выполнение этой функции (что неудивительно) занимает много времени, особенно цикла for в строке 302. Это занимает целых 20-30 секунд, а этот код защищен мьютексом, поэтому каждый второй поток пытается что-то сделать в блоках распределителя. Это возмущает наших клиентов.
Вопросы:
- Почему он внезапно выделил 6 ГБ, если до этого он постоянно запрашивал блоки ~ 200 МБ весь день?
- Можно ли как-то ограничить выделение? Я бы предпочел, чтобы он чаще просил мелкие кусочки.
- Это неправильный распределитель? Я предполагаю, что это вопрос к разработчикам быстрых исправлений, но, похоже, это их предпочтительный путь. Объекты, которые используют распределитель, в основном
std::map
иstd::multimap
.
MaxSize
, который, по-видимому, является ограничением на количество фрагментов, выделяемых базовым пулом за один раз, и по умолчанию он равен0
(вероятно, без ограничений). Вы изучили последствия просмотраMaxSize
ненулевым значением? - person Yakk - Adam Nevraumont   schedule 24.01.2015