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

前期在文章中贴出了自我实现的一个内存池,原理是针对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;
}
}
}

}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值