设为首页 加入收藏

TOP

C语言内存池使用模型(一)
2012-11-03 13:20:27 】 浏览:3749
Tags:语言 内存 使用 模型
    在用C语言开发时,特别是在服务器端,内存的使用会成为系统性能的一个瓶颈,如频繁的分配和释放内存,会不断的增加系统的内存碎片,影响内核之后分配内存的效率,这个时候一个比较可行的做法是采用内存池,先分配好比较多的内存,然后在这个已经分配的内存里使用内存,这样就不需要内核过多的参与内存分配和释放的过程。
   
    内存池根据应用不同有多种实现的策略,如有些分配很大的内存,然后将内存分配成大小相等的块,并将每个块链接起来进行管理。
   
    下面对模型介绍的时候,为了简单,不加入用于调试的编写技巧和为之准备的结构,其实主要是省去间接调用,有时为了调试,会将文件及所在行以及主要的变量状态输出。
   
    一、内存池访问接口
   
    创建大小为size的新的内存池。
   
    pool_t _pool_new_heap(int size);
   
    从指定内存池中分配大小为size的内存空间,这些空间会在内存池释放时,被自动的释放。
   
    void *pool_malloc(pool_t, int size);
   
    内存池的大小,返回内存池中所有内存块的大小总和
   
    int pool_size(pool_t p);
   
    释放内存池,这会导致所有内存被释放,同时内存池本身也被释放
   
    void pool_free(pool_t p);
   
    还有其它的一些接口,但这些是主要的接口。
   
    二、数据结构
   
    struct pheap
   
    {
   
    void *block;
   
    int size, used;
   
    };
   
    该结构表示内存池中一个内存块的抽象表示,
   
    1、block 用于指向由malloc所分配的内存地址。
   
    2、size 表示block所指向地址的内存大小。
   
    3、used 表示多少处于已经使用的状态。在分配内存时,这个域很重要,它表示内存块可以被分配的偏移值,也就是从used开始的内存都是可以被从内存池中分配出去的。
   
    struct pfree
   
    {
   
    pool_cleanup_t f;
   
    void *arg;
   
    struct pheap *heap;
   
    struct pfree *next;
   
    };
   
    typedef void (*pool_cleanup_t)(void *arg);
   
    这个结构用于实现一个链表,将所有的内存块链接起来。每一个内存块,对映一个这个结构,也就是每个struct pheap结构,都有一个struct pfree结构将其封装起来,这个结构主要实现下面几个功能:
   
    1、实现内存块的链表,用struct pfree *next连接起来,这是一个单链表。
   
    2、内存块释放的回调。注册在释放内存时,如果释放这个内存块,主要是通过pool_cleanup_t f和void *arg两个域来完成这个功能。
   
    3、pheap域用于指向需要被放入链表的内存块,就是前面的结构。
   
    typedef struct pool_struct
   
    {
   
    int size;
   
    struct pfree *cleanup;
   
    struct pfree *cleanup_tail;
   
    struct pheap *heap;
   
    } _pool, *pool_t;
   
    结构中的域代表如下:
   
    heap:指向内存池中最新申请的内存块,在每次申请内存块时,都会将其指向新的内存块。
   
    cleanup和cleanup_tail:指向链表的头和尾的指针。
   
    size:表示内存池中内存的大小,包括所有的内存块。
   
    这个结构的主要功能如下:
   
    1、管理内存块。通过cleanup和clean_tail两个指针,因为内存块在内存池中是以单链表的形式组织的,这两个指针分别指向链表的头和尾指针。
   
    2、内存池中可用的内存大小。通过size域来统计完成。
   
    3、获取最新的内存块指针。通过heap指针在每次分配内存块时重新赋值来实现。
   
    这个内存池的实现,主要是依靠上面三个数据结构来完成,其实估计已经知道的差不多了。下面再讨论一些基本的
   
    三、创建一个空的内存池
   
    创建一个空的内存池比较简单,就是初始化一个内存池结构,也就是pool_t结构,并将其链表置为NULL,大小为0,不包含任何的内存块。
   
    pool_t _pool_new()
   
    {
   
    pool_t p;
   
    while((p = malloc(sizeof(_pool))) == NULL) sleep(1);
   
    p->cleanup = NULL;
   
    p->heap = NULL;
   
    p->size = 0;
   
    return p;
   
    }
   
    四、创建指定大小的内存池
   
    创建一个包含大小为size内存块的内存池,这个操作分两步,先创建一个空的内存池,然后再创建一个内存块,并将该内存块加入内存池中,也就是将内存块加到内存池的链表末尾,并重新设定指针。
   
    pool_t _pool_new_heap(int size)
   
    {
   
    pool_t p;
   
    p = _pool_new();
   
    p->heap = _pool_heap(p,size);
   
    return p;
   
    }

     

首页 上一页 1 2 3 4 5 6 7 下一页 尾页 1/7/7
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇C小程序 - 信号量 下一篇C语言的技巧知识

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目