std::map的clear()没有用?
昨天晚上,我徒弟跑过来讲,他的程序的内存占用居高不下,愿意是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()没有用?的更多相关文章
- C++ std::map
std::map template < class Key, // map::key_type class T, // map::mapped_type class Compare = less ...
- std::map用法
STL是标准C++系统的一组模板类,使用STL模板类最大的好处就是在各种C++编译器上都通用. 在STL模板类中,用于线性数据存储管理的类主要有vector, list, map 等等.本文主要 ...
- 由STL map调用clear后,内存不返还给操作系统的问题出发,探讨glibc malloc/free行为(转)
1. 问题 我们的程序有几十个线程,每个线程拥有一个std::map,每个线程都要向自己的std::map中插入大量的数据,但每个数据只有几十字节:当使用完std::map,调用map.clear() ...
- C++ std::map::erase用法及其陷阱
1.引入: STL的map中有一个erase方法用来从一个map中删除制定的节点 eg: map<string,string> mapTest; typedef map<string ...
- std::map
1.例: map<int,string> m_mapTest; m_mapTest.insert(make_pair(1,"kong")); m_mapTest.ins ...
- std::map的操作:插入、修改、删除和遍历
using namespace std; std::map<int,int> m_map; 1.添加 for(int i=0;i<10;i++) { m_map.insert(mak ...
- 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 ...
- Std::map too few template arguments
在上述的代码中,红色波浪线的部分编译的时候报错: error C2976: 'std::map' : too few template arguments 换成std::map<std::str ...
- 使用std::map和std::list存放数据,消耗内存比实际数据大得多
使用std::map和std::list存放数据,消耗内存比实际数据大得多 场景:项目中需要存储一个结构,如下程序段中TEST_DATA_STRU,结构占24B.但是使用代码中的std::list&l ...
随机推荐
- 【wikioi】1250 Fibonacci数列(矩阵乘法)
http://wikioi.com/problem/1250/ 我就不说这题有多水了. 0 1 1 1 矩阵快速幂 #include <cstdio> #include <cstri ...
- const 与指针
深入理解const char*p,char const*p,char *const p,const char **p,char const**p,char *const*p,char**const p ...
- erlang-jiffy 安装手记
今天安装 erlang-jiffy 把握逼疯,不过最后还是成功了. 错误避免: rebar只能再英文目录下运行,如果编译jiffy的目录中有中文或其它unicode字符,将会出错 从git relea ...
- MyEclipse 10 之下Web Service 的创建和实现
(一)Web service服务端开发 1. 新建一个Web service project, 菜单New -> Web Service Project, 2. 新建一个 Java Bean, ...
- hdu A计划
这道题是一道bfs的题目,因为题目中给的数据很小,所以可以采用优先队列的方式来简化处理.这道题在搜索的过程中要注意map1的不同层次的转换,即对'#'的理解.之前wa了两次是因为我考虑了如果上下两层对 ...
- WPF之拖动项滚动条自滚动(当拖动项到达高度的边界时候滚动条自己可以上下滚动)
参考 http://www.cnblogs.com/ListenFly/p/3281997.html Point svPoint = e.GetPosition(sv); if (sv.ActualH ...
- C#生成日期流水账号
生成类似 LS14120002 private String GenNewOrder() { String newOrder; var orders = LYOrder.Items; String l ...
- Git Shell使用笔记
1,首次打开Git shell错误(以前打开过gethub客户端) 警告: git command could not be found. Please create an alias or add ...
- 如何用Apache POI操作Excel文件-----如何用Apache POI 画一个离散图
有的时候,我们需要Excel中的数据,通过一个图画,可视化的表现出来. 那么这个时候,应该如何做呢?现在就借花献佛,以Apache POI自己提供的一个例子为例,给大家演示一下POI的API 如何画图 ...
- 用thinkphp进行微信开发的整体设计思考
用thinkphp进行微信开发的整体设计思考 http://www.2cto.com/weixin/201504/388423.html 2015-04-09 0个评论 作者:明 ...