[原创]针对linux内存管理对前期内存池作出如下简化处理

本文探讨了在Linux系统下,作者对原有的内存池管理策略进行优化,以适应Linux的malloc优化。通过调整内存池的附加信息和管理策略,使得在特定内存大小范围内,自定义内存池能提供比系统malloc更高的效率。作者简化了内存池结构,仅在16到32K字节之间使用自定义内存池,其他则依赖于系统。这一改进减少了内存开销,提高了性能。
   前期在文章中贴出了自我实现的一个内存池,原理是针对initPool以内的 Align对齐(8、16...)的内存采用数组+练表表双重管理,以求达到高校的目的,每个内存项有2个字节是用来记录内存大小的,然后在Free中可 以将其对应回归到相应的桶内,InitPool以外的部分直接以链表的形式组织,这样就可以达到处理管理绝大多数内存的目的,在windows上测试性能 要远远高于直接malloc、free,但是在linux上发现情况有所改变,linux的malloc已经经过了内存池的优化处理,所以这个方安在 linux上看起来是画蛇添足,但是经过自己测试辨认发现还是有回旋的余地。
   这是我的当初内存项添加的数据
   typedef union _MemItem
       {
          short size;
          union _MemItem *next;
       }MemItem;
这是linux自身malloc内存池附加的标记
struct mem_block {
    int is_available;    //这是一个标记
    int size;            //这是实际空间的大小
    };
显然的哦的更为合理有效,正常情况下只需要附加2个字节,但是linux的malloc需要至少8个字节,随后在测试中发现linux的malloc内存 池对于不同断的内存采取不同的管理方式,大约是80字节以前的分配效率是很高的,大于80以后is_available项就不是0或者1这两个值,而是 80的倍数,不明白意思,也不需要知道,只知道在此之后我的内存池就有接管的必要了,为了更好的配合linux,我将自己附加在内存中的值去掉了,合用系 统自身的,然后仅仅笃定是用InitPool个数的控制,比如我在测试中选用的是2000,那么所有申请内存在16*16-2000*16(后面的两个 16是Align步进,也就是256字节到32K之间的)之间的都转由我自定义的内存池控制,基本能够满足用户程序的需求,小于256的部分在加线程锁的 控制后系统本身的还要更优,过大的没有必要加以控制,这样就可以直接交给malloc free处理
   综上,我将以前windows上较为复杂的内存池改成如下简化形式:

     memorys.h


/*
* File:   memorys.h
* Author: net
*内存池
* Created on 2008年4月27日, 上午9:59
*/

#ifndef _MEMORYS_H
#define    _MEMORYS_H

#ifdef    __cplusplus
extern "C" {
#endif

#define InitMemPool 1000 //初始化池所能拥有的数量,不能超过255*255
#define Align 16       //对齐步进单位,4,8,16等等,每项所能容纳的最大内存为Align*index,index为short int,所以单项最大容量为Align*255*255字节,4字节对齐最大为260K,8字节对齐为512K
#define InitMemItem 12 //初始化池所能拥有的数量不能超过255*255
#define ExpendMemItem 12 //每次扩展池多少项。不能超过255*255
#define MaxMemory 1024*1024*300 //内存池最大容量 300M
#define MinBlock 256 //这是本内存池与malloc性能分界线的一个最小数字
#define MaxBlock Align*InitMemPool //超出上限
#define MinIndex 16 //pool Index所代表的大小不是从Align(16K)开始的
#define new(type) ((type *)(New(sizeof(type))))
#define sizes sizeof(MemPool)

#include "types.h"

/**
*该结构用一个自增长的链表结构体保存分链表,每个结构体中包含具体链表的头部、尾部和空闲分界线指针,维护一个链表
*大致结构如下:
*            MemPool
*     V       V      V      ...
*   链表1   链表2   链表3   ...
*通过这样一个结构系统就可以灵活增加减少系统池,并且可以控制池内结构,控制总数据量
*
*/



typedef struct _MemItem
{
    struct _MemItem *next;
}MemItem;

struct mem_block {
    int is_available;    //这是一个标记
    int size;            //这是实际空间的大小
    };

/*池集合*/
typedef struct _MemPool
{
    int name;//名称,同item_size,不管什么类型,申请的同一大小内存快放在同一个内存管理区域,视为同一名称,
    long max_memory;//最多占用的内存
    int init_item;//初始化多少item
    int per_expend_item;//每次扩展时一次申请多少项
    int current_item;//当前有多少项被使用
    int total_item;//共有多少项
    MemItem * first;//IO池头地址
    MemItem * last;//IO池最后一项的地址
    MemItem * current;//IO池分割空闲和使用中的分割地址
}MemPool;




/**
*取会给定结构的池结构体
*/
static Int AlignNum(Int size);
void InitPoolItem(unsigned int name);
void InitPool(void);/*初始化池*/
void FreePool(MemPool * p);/*释放池*/


void InitItem(unsigned int name);//初始化具体项的链表
void *New(unsigned int size);//初始化具体项的链表
void ExpendItem(unsigned int name);//初始化扩展项的链表
void Free(void *myp);//释放具体一项
void PrintPool(void);


#ifdef    __cplusplus
}
#endif

#endif    /* _MEMORYS_H */

memorys.c
/*
* File:   memorys.c
* Author: net
*
* Created on 2008年4月27日, 上午9:58
*/

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
/*
*
*/
#include "memorys.h"
#include "types.h"


pthread_mutex_t Memlock;

int indexs=1;
MemPool poolIndex[InitMemPool];
//Lock memLock;
static long totalByte;

/**
*取会给定结构的池结构体
*/


/*新定义一个池项*/
void InitPoolItem(unsigned int name) {
   
    MemPool p = poolIndex[name-MinIndex];
    /*基本链表设置*/
    p.name = name;
    p.first = NULL;
    p.last = NULL;
    p.current = NULL;
    /*设置杂项*/
    p.max_memory = 0;
    p.init_item = 0;
    p.per_expend_item = 0;
    p.current_item = 0;
    p.total_item = 0;
}

/*初始化池*/
void InitPool(void) {

    pthread_mutex_init(&Memlock,NULL);
    int i;
    MemPool p;
    for (i = 0; i < InitMemPool; i++) {
        p = poolIndex[i];
        /*基本链表设置*/
        p.name = i + MinIndex;
        p.first = NULL;
        p.last = NULL;
        p.current = NULL;
        /*设置杂项*/
        p.max_memory = 0;
        p.init_item = 0;
        p.per_expend_item = 0;
        p.current_item = 0;
        p.total_item = 0;
    }

}
void FreePool(MemPool *p)
{
    pthread_mutex_destroy(&Memlock);
    return;
}


/*初始化项*/
void InitItem(unsigned int name)
{
    int blk;
    MemItem *ip;/*项的链表指针*/
    /*构造容器*/
    MemPool *p=&poolIndex[name-MinIndex];

    (p->total_item)+=((p->init_item)==0?InitMemItem:(p->init_item));
    p->first=(MemItem *)malloc(name*Align);/*创建第一个块*/

    ip=p->first;
    for(blk=1;blk<(p->init_item==0?InitMemItem:p->init_item);++blk)
    {
        ip->next=(MemItem *)malloc(name*Align);
        ip=ip->next;
    }
    ip->next=NULL;
    p->last=ip;
   totalByte+=name*Align*(p->init_item==0?InitMemItem:p->init_item);
   
}
/*扩展当前池项的下属内存块*/
void ExpendItem(unsigned int name)
{
    int blk;
    MemItem *ip;/*项的链表指针*/
    /*构造容器*/
   
    MemPool *p=&poolIndex[name-MinIndex];

    p->total_item+=(p->per_expend_item==0?ExpendMemItem:p->per_expend_item);
    p->last->next=(MemItem *)malloc(name*Align);/*创建第一个块*/
    indexs++;
    ip=p->last->next;
    for(blk=1;blk<(p->per_expend_item==0?ExpendMemItem:p->per_expend_item);++blk)
    {
        ip->next=(MemItem *)malloc(name*Align);
        ip=ip->next;
        indexs++;
    }
    ip->next=NULL;
    p->last=ip;
    totalByte+=name*Align*(p->per_expend_item==0?ExpendMemItem:p->per_expend_item);
    //printf("kuozan ");

}
/*申请心内存-〉内存池*/
void *New(unsigned int size)
{
    //MemItem *ip;/*项的链表指针*/
    /*构造容器*/
    if(totalByte>MaxMemory)
        return NULL;/**申请的总内存过大,请调大默认最大内存设置或者检察内寻泄露*/
     //    printf("新大小: %d ",size);
    if(size>=MaxBlock||size<MinBlock)
    {
        return malloc(size);
    }
    size=((size+Align-1) &~ (Align-1))/Align;
      // printf("oo: %d ",size);
    MemPool *p=&poolIndex[size-MinIndex];
   
    if(p->first==NULL)
       InitItem(size);

        pthread_mutex_lock(&Memlock);
    if(p->first->next==NULL)
    {ExpendItem(size);}

    MemItem *ips;
    ips=p->first;
    p->first=p->first->next;
    p->current_item++;
    pthread_mutex_unlock(&Memlock);
    return ips;/*此处返回的是向后偏移过的指针*/



}

/*内存池回收*/
void Free(void *myp)
{

       struct mem_block * realsize=(struct mem_block *)myp;//转化为Short指针
    --realsize;/*向前移动short位移*/
   //    printf("释放:%i,%i",realsize->size,realsize->is_available);
       int size=realsize->size-9;
       ++realsize;
      
      if(size>=MaxBlock||size<MinBlock)
    {
        free(realsize);
        //printf("直接释放了一个大于管理范围的内存指针,最大值255*255*4 /n");
        return;
    }
        
      // printf("gg0:%d",size);
       size=((size+Align-1) &~ (Align-1))/Align;
      //         printf("gg1:%d",size);
    MemItem *ip=(MemItem *)realsize;/*转化回来*/
    MemPool *p=&poolIndex[size-MinIndex];

    if(p==NULL)
    {
        printf("试图释放一个不属于池的指针,直接释放了/n");
        return;
    }
      pthread_mutex_lock(&Memlock);
    if(p->first!=NULL)
    {
       
        ip->next=NULL;
        p->last->next=ip;
        p->last=p->last->next;
        p->current_item--;
       
    }
    else
    {
        printf("产生了一个野指针");
    }
pthread_mutex_unlock(&Memlock);
    return;
}
/*输出调试函数*/
void PrintPool(void)
{
    MemPool *pool;
        int i;
    for (i = 0; i < InitMemPool; i++) {
            pool=&poolIndex[i];
            if(pool->first!=NULL)
            {
        printf("/n名称%i 共有%i 使用%i,初始化:%i 当前地 址%p/n",pool->name,pool->total_item,pool->current_item,pool->init_item,pool->current);
        if(pool->total_item>0)
        {
            MemItem * mi=pool->first;
            while(mi!=NULL)
            {
                printf("--/t%p",mi);
                mi=mi->next;
            }
        }
            }
       
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值