C++STL中map内存彻底释放方法_c++ map 手动释放-程序员宅基地

技术标签: 内存释放  unordered_map  计算机程序原理  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);
}

内存被释放

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zenhox/article/details/103350719

智能推荐

Bert 代码详细解读——modeling.py-程序员宅基地

文章浏览阅读4k次,点赞4次,收藏38次。在官方的bert-github上,git clone https://github.com/google-research/bert.git主要的文件内容如下图:主要包括7个主要的python文件,小编要坚持把这7个解读清楚呀!首先解读的是modeling.py文件,是bert实现的核心代码,主要包括2个类和17个函数,如下所示:一、类1.class Bert...

Spring Boot:数据库的整合_如何在spring boot应用中整合数据库-程序员宅基地

文章浏览阅读5.7k次,点赞45次,收藏53次。Spring Boot数据库的整合介绍_如何在spring boot应用中整合数据库

java8中的default关键字_default uhotkey-程序员宅基地

文章浏览阅读190次。在学习集合代码时发现在Iterable接口中使用了default关键字。default关键字介绍default是在java8中引入的关键字,也可称为Virtualextension methods——虚拟扩展方法。是指,在接口内部包含了一些默认的方法实现(也就是接口中可以包含方法体,这打破了Java之前版本对接口的语法限制),从而使得接口在进行扩展的时候,不会破坏与接口相关的实现类代码。为什么要有这个特性?首先,之前的接口是个双刃剑,好处是面向抽象而不是面向具体编程,缺陷是,当需要修改接口时候,需_default uhotkey

java垃圾分类系统(ssm)-程序员宅基地

文章浏览阅读878次,点赞19次,收藏20次。随着社会经济的快速发展与人口的持续增长,城市生活垃圾的产生量日益增多,垃圾处理问题成为摆在各大城市面前的一大难题。传统的混合收集、集中填埋或焚烧的处理方式不仅耗费大量的土地资源,而且容易造成环境污染和资源的浪费。垃圾分类作为解决这一问题的有效手段,通过将生活垃圾按照其性质分为可回收物、有害垃圾、湿垃圾(厨余垃圾)和干垃圾等类别进行分别处理,可以显著提高资源的回收利用率,减少对环境的污染。然而,由于公众环保意识的不足、分类系统的不完善以及相关设施的缺乏,导致垃圾分类工作难以有效推行。

[linux基础]基于fdisk磁盘分盘与挂载_fdisk新建分区挂载-程序员宅基地

文章浏览阅读189次。你可以按回车键使用默认的值,或按照需求指定分区的大小,可以根据p显示的分区表,选择上一个分区的end+1作为分区的start,大小计算一般是 1G = (1 * 1024 * 1024 * 1024) / 512,也可以选择使用**+1G**,end输入数值或者+1G都可。可以看到已经挂载的mmcblk0p1占未挂载的mmcblk0的7.2G(未挂载29.8-7.2G)在创建新分区后,你可以使用以下命令重新加载分区表,使新分区生效。根据提示输入分区类型,通常选择主分区(输入。接下来要输入命令自定义分区。_fdisk新建分区挂载

生成式AI时代,AI副业变现资源汇总-程序员宅基地

文章浏览阅读1k次,点赞23次,收藏24次。这是一个ai副业赚钱资讯信息的大合集,将在全网搜索并整理ai副业赚钱的相关方法、技术、工具、以及一些可以赚钱的平台和渠道。期望能在AI时代,打破信息茧房,让大家都能在这个时代利用AI智能化做副业,赚取工作之余的额外收益。

随便推点

rpm命令应用-程序员宅基地

文章浏览阅读3.5k次。记录:323场景:在CentOS 7.9操作系统上,使用rpm命令安装、卸载、查看软件包。_rpm命令

Ubuntu完整卸载postgresql_ubuntu22.04 卸载postgresql-程序员宅基地

文章浏览阅读2.1w次,点赞2次,收藏30次。删除相关的安装sudo apt-get --purge remove postgresql\*删除配置及文相关件sudo rm -r /etc/postgresql/sudo rm -r /etc/postgresql-common/sudo rm -r /var/lib/postgresql/删除用户和所在组sudo userdel -r postgressudo groupdel_ubuntu22.04 卸载postgresql

Ubuntu16.04下Caffe环境搭建的坑之import caffe 报错AttributeError: ‘numpy.ufunc’ object has no attribute‘module’_object has no attribute 'module-程序员宅基地

文章浏览阅读2.6k次。Ubuntu16.04系统下Caffe环境搭建的坑之import caffe 报错:AttributeError: ‘numpy.ufunc’ object has no attribute ‘module’这个错误是numpy版本不兼容的原因。我之前安装的是numpy1.1.6,一直报上面的错。然后找了几十篇博客才发现是numpy版本的原因。我建议安装numpy1.11.0。解决步骤:1...._object has no attribute 'module

Java复习——多线程_java多线程复习-程序员宅基地

文章浏览阅读181次。Java多线程和四种线程实现方式_java多线程复习

18. 离职原因:让 BOSS 学习“滚动加载”这一名词_滚动加载 python flask-程序员宅基地

文章浏览阅读1.4w次,点赞2次,收藏3次。本案例最后一个步骤时补齐JS代码,经过反复测试 ,插件的引入和使用需要在 DOM 对象之后,代码如下。_滚动加载 python flask

IDEA项目目录结构视图无法显示--原理剖析及解决方案_idea 视图选不了项目了-程序员宅基地

文章浏览阅读1.5k次,点赞14次,收藏14次。项目成功建立后,关闭IDEA,再次打开项目,发现项目的目录结构视图“莫名消失”?如图所示。_idea 视图选不了项目了

推荐文章

热门文章

相关标签