Как заставить мою std:: map освобождать используемую память?
Я использую std:: map, и я не могу освободить память обратно в ОС. Похоже,
int main(){
aMap m;
while(keepGoing){
while(fillUpMap){
//populate m
}
doWhatIwantWithMap(m);
m.clear();//doesnt free memory back to OS
//flush some buffered values into map for next iteration
flushIntoMap(m);
}
}
Каждый (fillUpmap) выделяет около 1gig, поэтому я очень заинтересован в том, чтобы вернуть его в свою систему, прежде чем он поглотит всю мою память.
Ive испытал то же самое с std::vector, но там я мог заставить его освободиться, выполнив обмен с пустым std::vector. Это не работает с картой.
Когда я использую valgrind, он говорит, что вся память освобождена, поэтому это не проблема с утечкой, так как после прогона все хорошо очищается.
изменить:
Сброс должен появиться после очистки.
Ответы
Ответ 1
m.clear()
освобождает память обратно в кучу, но для реализации кучи не рекомендуется выводить обратно обратно в ОС (даже если это возможно, такие проблемы, как фрагментация, затрудняют).
Так работает распределитель по умолчанию, если вы указали свой собственный распределитель для карты, он может иметь свой собственный кеш. Однако даже в этом случае он должен быть кэширован, чтобы в любом случае повторно использовать его.
Карты не имеют понятия емкости и размера, как это делают векторы.
Ответ 2
Это поведение нормальное, библиотека времени выполнения сохраняет память, выделенную классом карты, доступной для процесса, так что в следующий раз, когда ему нужно выделить память, ему не нужно идти в операционную систему. Это оптимизация библиотеки времени выполнения.
Ответ 3
Если вы создадите карту в куче (через новую), ее удаление освободит любую используемую память.
Ответ 4
Я проделал простой тест, когда я поместил некоторые данные в std:: map и затем вызвал std:: map:: clear().
typedef std::map<int, unit_t,std::less<int>,
my_allocator<std::pair<const int, unit_t>, 4 > > contaner_t;
contaner_t keys;
keys[1] = 10;
keys[2] = 20;
keys[3] = 30;
keys.clear();
это результат ввода printf в мой тест:
Allocator # 4, Memory consumption: 56 (allocated : 56)
Allocator # 4, Memory consumption: 112 (allocated : 56)
Allocator # 4, Memory consumption: 168 (allocated : 56)
Allocator # 4, Memory consumption: 112 (deallocated : 56),
Allocator # 4, Memory consumption: 56 (deallocated : 56),
Allocator # 4, Memory consumption: 0 (deallocated : 56),
Я думаю, вам, вероятно, также следует проверить поведение распределителя, но я думаю, что ваш стандартный std:: allocator по умолчанию освобождает память, как вы ожидаете, но эта память не возвращается в ОС. Кстати, какую ОС вы используете?
Вопрос в том, как вы измеряете can't seem to free the memory back to the OS.
и как вы можете быть уверены, что I could force it to free by doing a swap with an empty std::vector.
Вы действительно уверены, что выделенная память фактически возвращается к ОС?
Ответ 5
Возможно, вы могли бы создать собственный распределитель или просто использовать библиотеку пула Boost.
Ответ 6
Сменить трюк? Я знаю, что вы делаете это с помощью векторов и т.п., Но я сделал это с картами раньше.
Ответ 7
Я полагаю, вы работаете в Linux.
Если вам действительно нужно минимизировать объем памяти вашего приложения, вы можете вызвать malloc_trim() после очистки карты. Я бы также порекомендовал взглянуть на manlopt() manpage - там есть некоторые подсказки о том, почему ваш код может сохранять память, а не возвращать ее в ОС.