在以下测试程序中,std::map
分配的内存未被释放。总而言之,我们分配大约2.2 GB的内存,虽然我们使用空容器进行交换,但它从未发布过。
将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;
}
答案 0 :(得分:10)
std::map
的内部使用黑/红树来存储对象,其中包含许多小对象,但std::vector
使用大型平面内存块连续存储对象。
glibc
以不同的方式维护不同类型的内存。
在请求小对象时,通常使用内存池来避免外部碎片,但在释放对象时会导致内部碎片,内部碎片永远不会返回系统。
当请求大块时,glibc分配一个大的内存块,它可能包含外部片段。但释放后,内存将返回系统。