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/
最新文章
- 关于MJRefresh的下拉加载数据bug
- canvas学习和面向对象(二)
- php使用$_SERVER[";REMOTE_ADDR";]获取访问IP地址
- List集合的迭代器方法
- C++回顾map的用法
- ThinkPHP入门(二)
- Silverlight 读取配置文件
- 通过dbms_xplan.display_cursor识别低效的执行计划
- oracle----删除数据
- Windows phone 之自定义控件(补充)
- 编译osg for android
- 使用LVM进行分区扩展的记录
- liunx定时任务
- IDEA 上 Tigase8.0 源代码编译运行
- 28.实现 strStr() 函数
- E. Segment Sum(数位dp)
- M1/M2总结
- C# 面向对象的封装、继承、多态
- C#中富文本编辑器Simditor带图片上传的全部过程(MVC架构的项目)
- 2017-11-29 由runnable说起Android中的子线程和主线程
热门文章
- 【BZOJ】1179: [Apio2009]Atm(tarjan+spfa)
- Linux下PS命令详解
- github配置
- [转载]CString类常用方法----Left(),Mid(),Right()……
- [转] - Ubuntu 安装Eclipse
- hdu Robberies
- [转]IE11下Forms身份认证无法保存Cookie的问题
- UVA 796 Critical Links(Tarjan求桥)
- explicit关键字
- Mac 配置环境变量