C++ map数据清理clear效率及彻底释放内存
模拟实际生产情况的测试代码,map中的value保存的是对象。
#include<map> #include<vector> #include<string> #include <iostream> #include <time.h> using namespace std; class useTest { public: useTest() {}; map<string,string> testMap; vector<string> testVertor; string id; }; void clearData(map<int, useTest>& needClearMap) { clock_t startt = clock(); //分别通过去注释测试下面四种情况 //使用clear needClearMap.clear(); //使用swap //map<int, useTest> uu; //needClearMap.swap(uu); //使用erase //needClearMap.erase(needClearMap.begin(), needClearMap.end()); //使用for erase //for (auto iter = needClearMap.begin(); iter != needClearMap.end(); iter = needClearMap.erase(iter)) {} double sec = double(clock() - startt) / CLOCKS_PER_SEC; std::cout << "In Clear Cost Time:" << sec << endl; } void test() { map<int, useTest> needClearMap; for (size_t i = 0; i <= 10000; ++i) { useTest uT; for (size_t ii = 0; ii <= 1000; ++ii) { uT.testMap[to_string(ii)] = "我是测试,我是测试,我就是测试string"; uT.testVertor.push_back("我也是测试,我也是测试,我就是测试string"); } uT.id = to_string(i); //cout << i << endl; needClearMap[i] = uT; } clock_t startt = clock(); clearData(needClearMap); double sec = double(clock() - startt) / CLOCKS_PER_SEC; std::cout << "clearData Cost Time:" << sec << endl; } int main() { for (size_t i = 0; i < 10; ++i) { test(); } getchar(); }
测试结论
就单单实现某个map清空来说,swap效率最高,几乎是0耗时。但是当退出整个函数,释放swap转移到的临时对象要耗一定的时间。 erase效率稍微比clear高。通过for循环erase好似效率又高点。
内存释放:
STL容器调用clear()方法,通常只是使得容器内部的对象通通析构,但容器本身的内存无法得到释放。即篮子里面东西拿走了,篮子占的空间还在,这样是为了方便下次存放新的对象时,不需要再次申请空间。 其他同学的blog中有很多例子,即clear()后,容器的size为0,但capacity不变,
-
通过swap()空容器,来彻底释放容器占用的capacity.
对于map,set,unordered_map等容器,调用clear(), swap()都无法使得内存真正释放。虽然很多地方谈到,这一现象(内存被保留下来)是正常的,并不需要担心。但是当大量使用堆内存存放不同的数据结构,会造成严重的内存碎片从而导致内存泄漏问题。
解决方法
只需添加一行,malloc_trim(0); 这一行代码会将空闲的堆内存归还给操作系统,供其他进程使用。
#include <iostream> #include <map> #include <malloc.h> using namespace std; void func() { map<int,string> mp; int i = 5000000; while(i--) mp.insert(make_pair(i,string("hell000o"))); map<int,string>().swap(mp); } int main() { func(); cout <<"done."<<endl; malloc_trim(0); while(1); }