boost::shared_ptr имеет возможность использования так называемого «быстрого аллокатора» для внутренних нужд. Произвел тестирование этой возможности.
Включение быстрых аллокаторов производится определением макроса BOOST_SP_USE_QUICK_ALLOCATOR. Я добавил этот макрос в StdAfx.h перед заголовками буста и попытался пересобрать проект. Попытка прошла неудачно – выдалась ругань на функцию boost::size. Долго не мог понять, что ему надо, но, наконец, доперло. Оказывается, с определенных пор в Бусте имеется функция boost::size, раньше ее не было, а теперь она стала конфликтовать с некоторыми параметрами в шаблоне. В общем, мне оказалось достаточным исправить эти строки в boost/detail/quick_allocator.hpp:
Я заменил их на эти:
т.е. последовательность size заменил на size_". После этого пересборка проходит успешно.
Далее, я открыл свой любимый файл весом 80Мб. Особого прироста скорости я не заметил. Если он и есть, то меньше секунды – при общем времени открытия файла 6 секунд это малозначительно. Интересно другое. Общее потребление памяти существенно уменьшилось. Без быстрого аллокатора потребление составляло 209Мб. С аллокатором потребление составило 191Мб. Т.е. наблюдается очень даже существенное уменьшение.
Далее, обнаружилось, что при закрытии файла память практически не освобождается – потребление уменьшается, примерно, на 10Мб. Если файл открыть повторно, то потребление памяти возращается к прежнему уровню. Т.е. наблюдается поведение полностью аналогичное поведению MFC-шного CFixedAlloc для CString. Естественно, меня это не устраивает.
Есть, кстати, один любопытный нюанс. У быстрого аллокатора имеется параметр, позволяющий управлять размером блока, который будет использоваться для выделения памяти («BOOST_QA_PAGE_SIZE»). По умолчанию это 512 байт. В качестве эксперимента я поставил 1Мб. После этого при закрытии файла стало освобождаться гораздо больше памяти – потребление после закрытия стало падать до 80Мб (а раньше падало где-то до 180Мб). Учитывая, что аллокатор не отдает память обратно системе, данное поведение абсолютно предсказуемо.
После включения быстрого аллокатора стало наблюдаться стабильное падение программы при выходе. Небольшие раскопки сразу же выявили проблему: аллокатор использует статический мьютекс, который может уничтожаться раньше, чем другие статические объекты приложения. Поэтому, если эти объекты используют shared_ptr, то и будет наблюдаться подобное поведение. Вот небольшое обсуждение с участием одного из авторов shared_ptr: http://archive.netbsd.se/?ml=boost-dev&a=2008–02&t=6527030
Таким образом, получаем следующие итоги: