欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2024-02-17 15:17:22
...

最近遇到一个特别占内存的需求。使用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<int> vec(10000,-1);
   vector<int>().swap(vec);

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

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

实验现象

一段简单的代码看一下:

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

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

解决方法

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

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

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