前几篇文章对内存池做了两次改进和简化,因为在liunux上内存分配的malloc已经在系统的优化控制范围内了,所以一定范围内的内存分配还是交由系
统比较快,经测试基本上对于大于256字节的内存分配交由本内存池分配性能有明显提高,本次系统所有其他的对象都是构建在这个内存池之上,内存池会对用户
申请的内存作出二次归类管理
代码如下:
memeory.h
/*
* File: memorys.h:内存池管理系统
* Author: netpet
* Flower net server
*重要:实际的控制范围是最小值MinIndex*Align,最大值是(InitMemPool+MinIndex-2)*Align
* 本程序是为一体化web server产品专用设计,具有部分代码为具体产品优化而不代表普遍通用性的特性
* 程序在linux 2.46下调试通过,编辑工具netbeans 6.1 for c
*该结构用一个自增长的链表结构体保存分链表,每个结构体中包含具体链表的头部、尾部和空闲分界线指针,维护一个链表
*大致结构如下:
* MemPool
* V V V ...
* 链表1 链表2 链表3 ...
*通过这样一个结构系统就可以灵活增加减少系统池,并且可以控制池内结构,控制总数据量
* 联系方式:Email:netpetboy@163.com QQ:51977431
* Created on 2008年5月26日, 下午4:18
*/
#ifndef _MEMORYS_H
#define _MEMORYS_H
#ifdef __cplusplus
extern "C" {
#endif
#define InitMemPool 1000 //初始化池所能拥有的数量,不能超过255*255
#define new(type) ((type *)(New(sizeof(type))))
#define sizes sizeof(MemPool)
extern long MaxMemory;
extern int Align;
extern int InitMemItem;
extern int ExpendMemItem;
extern int MinBlock;
extern long MaxBlock;
extern int MinIndex;
typedef struct _MemItem {
struct _MemItem *next;
} MemItem;
/*
*该结构体是linux 2.4.6状态下malloc申请内存时强加的协议头结构,用来记录实际内存大小
*/
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;
/**
*取会给定结构的池结构体
*/
extern void InitPool(void); /*初始化池*/
extern void FreePool(); /*释放池*/
extern void InitItem(unsigned int name); //初始化具体项的链表
extern void *New(unsigned int size); //初始化具体项的链表
extern void ExpendItem(unsigned int name); //初始化扩展项的链表
extern void Free(void *myp); //释放具体一项
extern void PrintPool(void);
#ifdef __cplusplus
}
#endif
#endif /* _MEMORYS_H */
memorys.c
/*
* File: memorys.c:内存池管理系统
* Author: netpet
* Flower net server
*重要:实际的控制范围是最小值MinIndex*Align,最大值是(InitMemPool+MinIndex-2)*Align
* 本程序是为一体化web server产品专用设计,具有部分代码为具体产品优化而不代表普遍通用性的特性
* 程序在linux 2.46下调试通过,编辑工具netbeans 6.1 for c
*该结构用一个自增长的链表结构体保存分链表,每个结构体中包含具体链表的头部、尾部和空闲分界线指针,维护一个链表
*大致结构如下:
* MemPool
* V V V ...
* 链表1 链表2 链表3 ...
*通过这样一个结构系统就可以灵活增加减少系统池,并且可以控制池内结构,控制总数据量
* 联系方式:Email:netpetboy@163.com QQ:51977431
* Created on 2008年5月26日, 下午4:18
*/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <assert.h>
#include "memorys.h"
#include "log.h"
#include "config.h"
//内存池锁,现在还不确定是多锁性能更好还是总锁的性能好
pthread_mutex_t Memlock;
//内存池管理的项数范围,管理的最小为MinBlock,最大为InitMemPool*Align+MinBlock,除此之外的均交由malloc free自行管理
MemPool poolIndex[InitMemPool];
//Lock memLock;
static long totalByte;
//最大内存
long MaxMemory;
int Align;
int InitMemItem;
int ExpendMemItem;
int MinBlock;
long MaxBlock;
int MinIndex;
/*初始化池*/
void InitPool(void) {
MaxMemory = config->memory.MaxMemory;
MinIndex = config->memory.MinIndex;
Align = config->memory.Align;
InitMemItem = config->memory.InitMemItem;
ExpendMemItem = config->memory.ExpendMemItem;
MinBlock = Align*(MinIndex+1);
MaxBlock = (InitMemPool+MinIndex)*Align;
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;
}
printf("内存池初始化成功!\n");
}
/*
*释放内存池
*/
void FreePool() {
pthread_mutex_lock(&Memlock);
MemPool *pool;
int i;
for (i = 0; i < InitMemPool; i++) {
pool = &poolIndex[i];
if (pool->first != NULL) {
if (pool->total_item > 0) {
MemItem * mi = pool->first;
MemItem *ls;
while (mi != NULL) {
ls=mi;
mi = mi->next;
free(ls);
}
}
}
}
pthread_mutex_unlock(&Memlock);
pthread_mutex_destroy(&Memlock);
printf("Flower系统内存释放完毕!\n");
}
/*初始化项*/
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); /*创建第一个块*/
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;
}
ip->next = NULL;
p->last = ip;
totalByte += name * Align * (p->per_expend_item == 0 ? ExpendMemItem : p->per_expend_item);
}
/*
*申请新的内存块
*/
void *New(unsigned int size) {
//MemItem *ip;/*项的链表指针*/
/*构造容器*/
if (totalByte > MaxMemory)
return NULL; //申请的总内存过大,请调大默认最大内存设置或者检察内寻泄露
size = (size + Align - 1) &~ (Align - 1);
if (size >= MaxBlock || size < MinBlock) {
return malloc(size);
}
size = size / Align;
MemPool *p = &poolIndex[size - MinIndex];
if (p->first == NULL)
InitItem(size);
if (p->first == NULL)
Error("当前项初始化时发生了错误,可能原因为系统内存不足%p", p);
//防止检测初始化不成功导致的意外错误
assert(p->first);
pthread_mutex_lock(&Memlock);
if (p->first->next == NULL) {
ExpendItem(size);
//防止检测扩展项不成功导致的错误
if (p->first->next == NULL)
Error("当前项扩展时发生了错误,可能会导致内存池New死锁,可能原因为系统内存不足%p", p->first);
}
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位移*/
int size = realsize->size - 9;
++realsize;
if (size >= MaxBlock || size < MinBlock) {
free(realsize);
return;
}
size = ((size + Align - 1) &~ (Align - 1)) / Align;
MemItem *ip = (MemItem *) realsize; /*转化回来*/
MemPool *p = &poolIndex[size - MinIndex];
if (p == NULL) {
Error("试图释放一个不属于池的指针,直接释放了,当前size%d\n", size);
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 {
Error("产生了一个野指针,,当前size:%d", size);
}
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;
}
}
}
}
}
分享到:
相关推荐
C#074折中法猜数字 源代码
但是编写动态内存分配代码因ram有限又不适宜采用动态链表的方式来管理内存,采用固定分配块的方式又不能充分利用单片机的ram(有时候一个字节都很重要啊),为此想出这个在速度和ram使用效率折中的办法(因为在使用...
在悲观和乐观中折取中值,既不过于冒险,也不过于保守,先确定折中系数aa在0~1之间,a=0则为悲观决策,a=1则为乐观决策。将各个方案在各种自然状态下可能取得的最大收益指找出,用它乘以a,在加上最小收益值乘以1-a...
主要研究通过协同进化算法使得网络控制系统的性能和安全性达到最优折中。以DC运动系统为例,给出了性能和安全性的折中模型。同时还给出了基于协同进化算法的性能和安全性折中的最优化算法。实验结果证明协同进化算法...
折中分类性能的算法实现以正负类召回率的几何平均作为择优标准,选用了四类算法(基算法C4.5和ZeroR)依次在三组样本集上进行分类建模。与传统代价给定方式代入算法相比,寻优过程确定的代价因子代入AdaCost算法后,...
UARTx.H为公共代码文件,#include被包含在UART1.C,、UART2.C、……中(用UARTn.C指代)实现所有的接收、发送的中断处理函数,在UARTn.C中宏定义各中断向量函数名以及各种硬件相关参数,定义接收发送的内存缓冲区...
工具的基本功能就是汇编代码注入,我在注入的代码中加入了SEH和取返回值的代码 前段时间@KaQqi 问我这个注入工具怎么写短跳,我告诉他没法写,程序的逻辑没实现这个(才不会说是我没思路呢) 于是我想了一个折中的...
研究了如何对业务量工程中的两个重要目标:负载均衡和能量效率进行公平折中。...通过严格的数学证明,以及在NSFNET中的应用可以看出,提出的方案不仅易于实施,还能保证对负载均衡和能量效率两个目标折中的公平性。
第八章--沃尔多综合折中行政观.ppt
电气设备在其电磁环境中必须能正常运行并不对其环境中的任何设备产生无法忍受的电磁骚扰。
MIMO系统分集复用的折中算法研究,赵世光,张治,本文以MIMO系统模型为基础,分析了MIMO提供的分集增益和复用增益的优势和两者的折中关系,并且介绍了两种典型的空时编码方案。在充�
不做修改或者做很少修改,即可运行在 windows,linux,MacOS, iOS, andriod等平台。 下一个即将上传的资源就是利用这个代码,在iOS手机开启FTP服务,并且把手机相册映射成一个虚拟目录,提供给FTP客户端工具共享。
让你的 JetBrains 系 IDE ( IDEA ,PyCharm,PhpStorm,WebStorm,AndroidStudio,DevEco等 )支持中文标识符以拼音/五笔等输入方式完成代码补全,为代码表达提供更多选择,一种值得考虑的折中解决方案
电源的电磁干扰水平是设计中最难的部分,设计人员能做的最多就是在设计中进行充分考虑,尤其在布局时。由于直流到直流的转换器很常用,所以硬件工程师或多或少都会接触到相关的工作,本文中我们将考虑与低电磁干扰...
对多天线系统误码率性能进行了深入分析,针对以往研究多侧重于分别提高系统分集增益或复用增益,未能充分利用多天线系统性能的问题,提出了基于自适应码率、功率分配技术的多天线系统分集复用折中算法,并进一步给出...
固定和可变分区内存管理方法都存在缺陷。固定分区由于分区数目是固定的,因此限 制了活动进程的个数,而且当可用内存大小与进程内存需求大小不匹配时,内存使用效率非 常低效。而可变分区方法管理起来较为复杂,而且...
一般处理程序动态生成网页(折中发)利用一般处理程序 动态生成所需要的静态网页,里面包含数据库 还有代码源码 ,代码包含详细的注释
本文件使用小波阈值法图像去噪.包括软阈值,硬阈值,及折中阈值去噪,并在折中阈值去噪方法基础上加入自适应算法,得到较好结果.
顺序表子系统实现顺序查找,折中查找程序;
现代的C/C++类库一般会提供智能指针来作为内存管理的折中方案,比如STL的auto_ptr,Boost的Smart_ptr库,QT的QPointer家族,甚至是基于C语言构建的GTK+也通过引用计数来实现类似的功能。Linux内核是如何解决这个问题...