C++STL中map内存彻底释放方法

最近遇到一个特别占内存的需求。使用STL map/unordered_map,内存无法得到正确释放。再次响应请求,会出现内存溢出的情况。

[6453149.107435] Memory cgroup out of memory: Kill process 54949 (******) score 1001 or sacrifice child
[6453149.117193] Killed process 54779 (******) total-vm:106091668kB, anon-rss:104842716kB, file-rss:1088kB

传统的STL内存释放方法

我们知道,STL容器调用clear()方法,通常只是使得容器内部的对象通通析构,但容器本身的内存无法得到释放。即篮子里面东西拿走了,篮子占的空间还在,这样是为了方便下次存放新的对象时,不需要再次申请空间。
其他同学的blog中有很多例子,即clear()后,容器的size为0,但capacity不变,链接。

  • 通过swap()空容器,来彻底释放容器占用的capacity.
   vector vec(10000,-1);
   vector().swap(vec);

但是这种方法只对vector, string这两个容器有效,这里有大牛的解释;

对于map,set,unordered_map等容器,调用clear(), swap()都无法使得内存真正释放。虽然很多地方谈到,这一现象(内存被保留下来)是正常的,并不需要担心。但是当大量使用堆内存存放不同的数据结构,会造成严重的内存碎片从而导致内存泄漏问题。

实验现象

一段简单的代码看一下:

#include 
#include 
using namespace std;
void func()
{
        map mp;
        int i = 5000000;
        while(i--)
            mp.insert(make_pair(to_string(i),string("hell000o")));
        map().swap(mp);
}
int main()
{
        func();
        cout <<"done."<

持续使用top观察内存,发现内存一直持续为最后的峰值。
C++STL中map内存彻底释放方法_第1张图片

解决方法

只需添加一行,malloc_trim(0); 这一行代码会将空闲的堆内存归还给操作系统,供其他进程使用。

#include 
#include 
#include 
using namespace std;
void func()
{
        map mp;
        int i = 5000000;
        while(i--)
            mp.insert(make_pair(to_string(i),string("hell000o")));
        map().swap(mp);
}
int main()
{
        func();
        cout <<"done."<

C++STL中map内存彻底释放方法_第2张图片

你可能感兴趣的:(计算机程序原理)