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<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观察内存,发现内存一直持续为最后的峰值。
内存不会下降

解决方法

只需添加一行,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);
}

内存被释放

  • 7
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值