Должен ли я беспокоиться о фрагментации памяти с помощью std::vector?

должен ли я беспокоиться о фрагментации памяти с помощью std:: vector? Если да,то есть ли способы предотвратить это? Я не всегда предсказываю, что мои программы будут работать на ПК, они также могут работать на встроенных устройствах/игровых консолях, поэтому я не всегда смогу полагаться на виртуальную память.

опять же, я считаю, что было бы более эффективно использовать массив динамического размера, а не статический массив, так что память будет выделяться только при необходимости. Это также упростило бы мой процесс проектирования программ. Есть ли способы добиться этого эффективно?

Спасибо за любой совет!

6 ответов


ответ на ваши заботы может быть std::deque. Это дает вам аналогичный интерфейс для std::vector, но лучше работает с фрагментированной памятью, так как она выделяет несколько небольших массивов вместо большого. Это на самом деле менее эффективно, чем std::vector в некоторых аспектах, но в вашем случае это может быть хорошим компромиссом.


Если ваш вектор будет перераспределен много раз, то да, это может вызвать фрагментацию памяти. Самый простой способ избежать этого-использовать std::vector:: reserve() Если вы более или менее знаете, насколько велик ваш массив может расти.

вы также можете рассмотреть возможность использования std:: deque вместо вектора, поэтому у вас не будет проблем с фрагментацией памяти вообще.

вот тема на stackoverflow, которая может быть интересна для вас: что такое фрагментация памяти.


std::vector хорош только как новый. Он просто обрабатывает базовое выделение памяти для вас Несколько вещей, которые вы можете сделать - предполагая, что вы не хотите писать совершенно новый new обработчик.

предварительно выделить векторы или изменить размер () если вы знаете, какой конечный размер они будут, это останавливает расточительные копии памяти по мере их роста.

Если вы собираетесь использовать вектор снова с тем же размером, лучше сохранить его и пополнить его, чем удалить его и воссоздать его.

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


вы всегда должны беспокоиться о производительности и эффективности когда ваш профилировщик говорит вам так (вы можете быть этим профилировщиком, но вы должны "измерить", а не угадать).

вещи, которые вы можете сделать:

  1. предварительное распределение мощностей:

     std::vector<int> x(1000); // size() is 1000
    
     std::vector<int> y;
     y.reserve(1000); // size() is 0, capacity is 1000
    
  2. используйте пользовательский распределитель

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

для профилирования кучи, I предложите


один хороший способ минимизировать повторное выделение памяти и перераспределение вызовов с std::vector это либеральное использование std::vector::reserve() если у вас есть представление о том, сколько элементов будет использовать ваш вектор. Это позволит предварительно распределить емкость и предотвратить изменение размера внутреннего массива, который вектор поддерживает при добавлении элементов через push_back().


нет, std:: vector гарантирует непрерывное хранение. Вы можете использовать vector:: reserve (), чтобы избежать перераспределений по мере увеличения размера вектора.