zoukankan      html  css  js  c++  java
  • std::map的clear()没有用?

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

    代码如下:

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

    用命令 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(2);
        for(int i=0; i<1000000; i++)
        {
            testmap.insert(make_pair(i,"abc"));
        }
        malloc_stats();
        testmap.clear();
        malloc_stats();
    }
    
    int main()
    {
        release_map();
        getchar();
        return 0;
    }
    View Code

    发现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/

  • 相关阅读:
    OpenCV基本函数学习
    OpenCV:概述、结构和内容
    NS2典型例子简单分析
    NS2仿真过程中需要的语言及基本组件
    洛谷 P2393 yyy loves Maths II
    洛谷 P1922 女仆咖啡厅桌游吧
    洛谷 P2559 [AHOI2002]哈利·波特与魔法石
    洛谷 P1301 魔鬼之城
    洛谷 P2383 狗哥玩木棒
    洛谷 P2298 Mzc和男家丁的游戏
  • 原文地址:https://www.cnblogs.com/hero4china/p/std-map-clear.html
Copyright © 2011-2022 走看看