Подтвердить что ты не робот

Почему std:: map <std:: map> не освобождает память?

В следующей тестовой программе память, выделенная std::map, не освобождается. В общем, мы выделяем примерно 2,2 ГБ памяти, которая никогда не выпускается, хотя мы делаем своп с пустым контейнером.

При изменении std::map< std::map >, чтобы стать std::map< std::vector >, память фактически освобождена.

Я проверил код с valgrind, который явно не обнаруживает утечек.

Почему это так, и как я могу изменить поведение?

#include <cstdlib>
#include <iostream>
#include <vector>
#include <map>
#include <chrono>
#include <thread>

class Test
{
   public:
   std::vector< std::pair< int, int > > myContainer;
   std::map<int,int> myMap;

   Test(){
      for( int i = 0 ; i  < 10000; i++  ){
         std::pair<int, int> pair = std::make_pair<int, int>( rand(), int( i ) );
         //myContainer.push_back( pair );
         myMap.insert( pair );
      }            
   }
};

int main()
{

  std::map<int,Test> myContainer1;

   for( int i = 0 ; i < 5000; i++  ){      
      myContainer1.insert( std::make_pair<int, Test>( rand(), Test() ) ); 
   }      

   std::cout << "ready!" << std::endl;
   std::this_thread::sleep_for( std::chrono::milliseconds( 5000 ) );
   std::cout << "cleaning..." << std::endl;

   {
      std::map<int,Test> tmp;
      myContainer1.swap( tmp );
   }

   std::cout << "cleaning ready!" << std::endl;
   std::this_thread::sleep_for( std::chrono::milliseconds( 15000 ) );

   return 0;
}
4b9b3361

Ответ 1

внутренняя часть std::map использует черное/красное дерево для хранения объектов, которое содержит много мелких объектов, но std::vector хранит объекты непрерывно, используя большой плоский блок памяти.

glibc поддерживает различный тип памяти по-разному.

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

При запросе больших блоков glibc выделяет большой блок памяти, который может содержать внешние фрагменты. но при освобождении память вернется в систему.