内存管理之内存池的设计

来源:互联网 发布:流星网络电视apk安卓 编辑:程序博客网 时间:2024/05/21 12:41

http://hi.baidu.com/wuzsh/blog/item/9db9b63eda918cfc838b1368.html  

如何更好的管理在应用程序中内存的使用,同时提高内存使用的效率,这是值得每一个做开发的人深思的问题。内存池(Memory pool)提供了一种比较可行的解决方案。下面就一般内存池的原理与设计进行探讨。


    一般的内存池的使用,分为以下几个过程:

   1.创建内存池。这个过程的主要任务是预先分配足够大的内存,形成一个初步的“内存池”。这里在实现的过程中,具体可以这么做,因为应用程序中不同的地方需要的内存的大小不尽相同,所以要在内存池中放一些不同大小的内存块,这样能更好地满足应用程序对内存的需求,同时也能提高内存的使用率。举个例子,可以在内存池中放256B, 512B, 1K, 2K, 4K, 8K, 16K, ... , 1M, 2M, 4M大小的内存块。每种块的个数,可以根据实际情况定,用的频率比较高的块可以多分配一些,用得频率比较低的块少分配一些。在用C++实现的时候,我的建议是使用map<int, deque< pair<char *, bool> > >结构来管理这内存池中的这些内存,在该结构中,键为内存块的大小,值为所有大小为键的内存块的一个双向队列。该队列中,每个元素有两部分组成,第一部分是指向该内存块的指针,第二部分是该内存块是否空闲的标志。

    2.分配内存。每次用户要从内存中获取内存时,首先要计算出不小于用户所需要的内存大小的在我们的内存池中有的最小的内存块的大小。然后去内存池中找,这样大小的内存块是否有空闲的。如果有,就把这块内存返回给用户。如果没有的话,可以直接调用系统提供的malloc或是new分配一块内存,并且要把这块内存添加到内存池中,被把标志位置为已用状态。在这里,要注意的是,尽可能减少直接调用malloc或new的次数,否则内存池在效率上的优势就体现不出来了。内存池设计的优劣很大程度上也是在这里决定的。好的设计,可以保证miss率很低,这样就很好地发挥了内存池的优势。

   3.释放内存。内存的释放,不是真正地调用free或是delete的过程,而是把内存放回内存池的过程。在把内存放入内存池的同时,要把标志位置为空闲。

    4.销毁内存池。最后在应用程序结束时,要把内存池销毁。这里主要做的工作就是把内存池中的每一块内存释放。

     以上即阐述了一般的内存池的原理与设计。每个内存池的原理都是一样的,只是根据不同的应用程序,实现会可能会略有不同。

    最后还有几点要说明一下的:

    使用内存池的好处:
    1.减少了内存碎片的产生。这个可以从创建内存池的过程中看出。我们在创建内存池时,分配的都是一块块比较整的内存块,这样可以减少内存碎片的产生。
    2.提高了内存的使用效率。这个可以从分配内存和释放内存的过程中看出。每次的分配与释放并不是去调用系统提供的函数或是操作符去操作实际的内存,而是在复用内存池中的内存。

    缺点:
    1.有可能会造成少量的内存浪费。因为分配的内存,往往有可能大于用户实际所需的。但是这个带来的影响是很小的,实际上是瑕不掩瑜的。