昨天晚上,我徒弟跑过来讲,他的程序的内存占用居高不下,愿意是std::map的clear()没有效果。于是我让他用erase(begin,end); 试试也不行。

代码如下:

void release_map(void)
{
map<int,string> testmap;
for(int i=; i<; i++)
{
testmap.insert(make_pair(i,"abc"));
}
testmap.clear();
} int main()
{
release_map();
while()
{
sleep();
}
return ;
}

用命令 top -p `ps -ef | grep abc | grep -v grep | awk {'print $2'}`, 一查看,占了104M物理内存。

开始我猜测是stl用了自己的缓冲池,clear()并没有归还给系统。于是我用了boost::unordered_map试试,一查看,占了78M物理内存(看来hashmap比红黑树既快又省空间)。

于是上网查询资料,stl有很多种allocator,默认采用是的new_allocator,并没有使用内存缓冲池,针对不同的应用场合,STL中实现了不同的Allocator。

__gnu_cxx::new_allocator<T> Simply wraps ::operator new and ::operator delete.
__gnu_cxx::malloc_allocator<T> Simply wraps malloc and free. There is also a hook for an out-of-memory handler
__gnu_cxx::debug_allocator<T> A wrapper around an arbitrary allocator A. It passes on slightly increased size requests to A, and uses the extra memory to store size information. 
__gnu_cxx::__pool_alloc<bool, int> A high-performance, single pool allocator. The reusable memory is shared among identical instantiations of this type.
__gnu_cxx::__mt_alloc<T> A high-performance fixed-size allocatorthat was initially developed specifically to suit the needs of multi threaded applications
__gnu_cxx::bitmap_allocato A high-performance allocator that uses a bit-map to keep track of the used and unused memory locations

发现stl提供的malloc.h有监控功能,于是修改为下面代码:

#include <iostream>
#include <string>
#include <map>
#include <boost/unordered_map.hpp>
#include <malloc.h> using namespace std;
using namespace boost;
void release_map(void)
{
malloc_stats();
map<int,string> testmap;
sleep();
for(int i=; i<; i++)
{
testmap.insert(make_pair(i,"abc"));
}
malloc_stats();
testmap.clear();
malloc_stats();
} int main()
{
release_map();
getchar();
return ;
}

发现clear() 其实已经归还内存了,内存的持有是 system bytes 。显然,malloc并没有把这些内存归还给系统,而是缓存起来了。所以说,这个例子的罪魁祸首并不是STL,而是glibc的malloc。好吧,既然找到问题,那就要解决它,虽然glibc的缓存也是一番好意,但是由于实际运行环境不能等到什么用户heap空间内连续空闲内存数据超出一个阈值时才将这片内存归还给内核。

glibc管理内存目前采用的是ptmalloc2,我测试了google的tcmalloc和Jason Evans的jemalloc。

测试很简单,把包downlaod下来并解压,./configure && make && make install即可。

export $LD_PRELOAD="/usr/local/lib/libtcmalloc.so” 或者 export $LD_PRELOAD="/usr/local/lib/libjemalloc.so” (这个要根据自己的实际情况选择路径)

然后编译后可以用ldd查看程序的依赖库。

测试结果:tcmalloc也不归还给系统,而jemalloc的clear后不再占用物理内存。

徒弟问了一句jemalloc靠谱么,我想想淘宝的Tengine,facebook的folly,redis,firefox,freebsd都是用这个,应该是很靠谱的。你上线去测试看看。

附上一张内存分配性能比较图片:

参考文献:

http://blog.163.com/dengminwen@126/blog/static/870226720097189486788/

http://bbs.chinaunix.net/thread-2195511-1-1.html

http://wangkaisino.blog.163.com/blog/static/1870444202011431112323846/

std::map的clear()没有用?的更多相关文章

  1. C++ std::map

    std::map template < class Key, // map::key_type class T, // map::mapped_type class Compare = less ...

  2. std::map用法

    STL是标准C++系统的一组模板类,使用STL模板类最大的好处就是在各种C++编译器上都通用.    在STL模板类中,用于线性数据存储管理的类主要有vector, list, map 等等.本文主要 ...

  3. 由STL map调用clear后,内存不返还给操作系统的问题出发,探讨glibc malloc/free行为(转)

    1. 问题 我们的程序有几十个线程,每个线程拥有一个std::map,每个线程都要向自己的std::map中插入大量的数据,但每个数据只有几十字节:当使用完std::map,调用map.clear() ...

  4. C++ std::map::erase用法及其陷阱

    1.引入: STL的map中有一个erase方法用来从一个map中删除制定的节点 eg: map<string,string> mapTest; typedef map<string ...

  5. std::map

    1.例: map<int,string> m_mapTest; m_mapTest.insert(make_pair(1,"kong")); m_mapTest.ins ...

  6. std::map的操作:插入、修改、删除和遍历

    using namespace std; std::map<int,int> m_map; 1.添加 for(int i=0;i<10;i++) { m_map.insert(mak ...

  7. Using std::map with a custom class key

    From: https://www.walletfox.com/course/mapwithcustomclasskey.php If you have ever tried to use a cus ...

  8. Std::map too few template arguments

    在上述的代码中,红色波浪线的部分编译的时候报错: error C2976: 'std::map' : too few template arguments 换成std::map<std::str ...

  9. 使用std::map和std::list存放数据,消耗内存比实际数据大得多

    使用std::map和std::list存放数据,消耗内存比实际数据大得多 场景:项目中需要存储一个结构,如下程序段中TEST_DATA_STRU,结构占24B.但是使用代码中的std::list&l ...

随机推荐

  1. 【wikioi】1553 互斥的数(hash+set)

    http://wikioi.com/problem/1553/ 一开始我也知道用set来判a[i]/p是否在集合中,在的话就直接删掉. 但是我没有想到要排序,也没有想到当存在a,b使得a/p==b时到 ...

  2. eWebeditor编辑器上传图片路径错误解决方法[疑难杂症]【转,作者:unvs】

    做了一个多版本的网站,后台用的编辑器是eWebeditor,NET版,后面发现上传图片或者文件之后,路径错误无法显示,必须手工修改才行.. 为了更清楚的说明问题,我下面会说的比较详细,首先是网站文件框 ...

  3. Cite a Website in Paper 论文中引用网页的格式

    Template: 1.A. Author Surname, 'Title', Year Published, <http://Website-Url> (accessed 10 Octo ...

  4. lightning mdb 源代码分析(1)

    lighting mdb(lmdb) 是一个高性能mmap kv数据库,基本介绍和文档参见symas官网,本文将尝试分析其源代码结构以理解数据库设计的关键技术. 本系列文章将尝试从以下几个方面进行分析 ...

  5. Samba结合AD实现域帐号认证的文件服务器

    准备一台Windows域控制器, 在Samba服务器上安装Webmin图形化管理工具, samba, krb5-user, winbind. 修改/etc/krb5.conf. [logging] d ...

  6. 【新产品发布】【GK101 10MHz任意波发生器】

    简介: GK101 10MHz掌上任意波形发生器基于多项先进技术,在较小的体积上实现了普通台式仪器才具有的功能.仪器仅手掌大小,实现了80M采样率.10MHz最大频率.10Vpp最高幅度的输出. 仪器 ...

  7. velocity学习记录

    一.引入文件 静态引入:#include("./footer.vm.html") 动态引入:#parse("./header.vm.html") 说明:./为v ...

  8. UVALive 7297 bfs

    题意 一个小偷偷到了项链 他想知道自己是否可以逃出去 地图中有一个小偷 一个警察 警察有一条狗 一开始 小偷和警察的移动速度都是1 当警察走到小偷经过过的地方时 警察会有一条狗嗅到小偷的气味并且以2的 ...

  9. 39. 求分数序列前N项和

    求分数序列前N项和 #include <stdio.h> int main() { int i, n; double numerator, denominator, item, sum, ...

  10. VMware 虚拟机使用 NAT 方式联网

    选择要设置的虚拟主机: 点击右键,选择 “属性”,查看 “网络适配器”: 此时选择的连接方式是 “Host-only”,在 Host-only 模式中,所有的虚拟系统是可以相互通信的,但虚拟系统和真实 ...