前期在文章中贴出了自我实现的一个内存池,原理是针对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;
}
}
}
}
}
分享到:
相关推荐
在Linux系统中,内存池是一种优化内存管理的技术,尤其对于频繁分配和释放小块内存的情况,内存池可以显著提升性能并减少系统开销。本文将深入探讨Linux下的内存池实现,包括其原理、优势以及如何在C或C++中进行实践...
Linux内存管理是操作系统的核心组成部分,它负责...实验总结表明,通过实践操作,学生对Linux内存管理有了更深入的理解,并且能够应用于实际问题中,这对于未来深入学习操作系统和其他系统级编程有着积极的推动作用。
Linux 内存管理源代码导读 Linux 内存管理是操作系统中最重要的组件之一,它负责管理计算机的内存资源,确保系统的正确运行。在 Linux 操作系统中,内存管理是通过页框管理、Slab 算法和动态存储器管理来实现的。 ...
Linux内存管理笔记详细介绍了Linux操作系统内核中内存管理机制的关键知识点,下面将依次对这些知识点进行详细说明: 存储器的层次结构:计算机系统采用分层的存储子系统以在存储容量、访问速度、成本效益之间取得...
Linux 内存管理是操作系统核心的重要组成部分,它负责有效地分配、使用和回收系统内存资源。在Linux中,内存管理的设计非常复杂,以适应各种硬件架构和优化性能的需求。以下是Linux内存管理的一些关键知识点: 1. *...
"Linux虚拟内存管理" Linux操作系统中,虚拟内存管理是指使用磁盘作为RAM的扩展,以增大可用的内存大小。内核会将暂时不用的内存块的内容写到硬盘上,以便释放出内存空间供其他进程使用。当需要用到原始的内容时,...
提供的图像文件如"内存结构图1.gif"、"内存结构图2.gif"、"3G-4G线性地址内存分配.gif"和"zone.gif"、"node.gif"应该详细展示了Linux内存管理的各个层次,包括节点和区域的分布、3G-4G内存空间的划分以及内核对内存...
整个内存管理系统可以分为2部分来看待: 第一部分是对物理内存的管理, 第二部分是对虚拟内存的管理. 物理内存管理的对象是板载的物理内存(DDRAM), 它把物理内存按页划分, 并把这些页放到一个池子里面. 物理内存管理...
本文档是对Linux内核内存管理系统的一个深入分析,特别是针对其源代码进行了详细的解读。Linux的内存管理是内核中最复杂的部分之一,它涉及到了内存初始化、地址映射、请页、交换、分配与回收等多个方面。通过对这些...
Linux和Windows 2000操作系统在内存管理方面有显著的区别,这主要体现在它们的内存模型、页面替换算法、虚拟内存以及内存分配策略等方面。以下是对这些知识点的详细阐述: 1. **内存模型** - **Linux内存模型**:...
### Linux内存管理介绍 #### 虚拟内存与Linux 在深入探讨Linux内存管理之前,我们先了解一下虚拟内存的基本概念及其在Linux系统中的应用。虚拟内存是一种计算机内存管理技术,它通过将进程的虚拟地址空间映射到...
Linux操作系统内存管理 Linux操作系统的内存管理是计算机科学中一个重要的领域。本文将详细阐述Linux操作系统的内存管理机制,包括物理内存和虚拟内存的管理机制、地址映射机制、内存碎片和内存不连续的问题解决等...
Linux内存管理是操作系统的核心组成部分,它负责有效地分配、管理和回收内存资源。在Linux环境中,程序员通常通过系统调用和库函数来与内存管理接口交互。本实验主要关注两个方面:一是使用malloc()函数进行内存分配...
linux内存管理工具
Linux内存管理是操作系统管理计算机内存资源的重要组成部分,它涉及到内存的分配、回收以及效率优化等多方面的技术。Linux内存管理采用的是一种三级架构模型,包括内存节点(node)、内存区域(zone)和物理页框(page)。...
内存池通过预先分配一大块连续的内存区域,并对其进行分割和管理,为应用程序提供内存分配服务,以此来提高内存利用率,减少碎片,提高系统性能。下面我们将详细探讨Linux内存池的原理、实现方式以及代码实例。 一...
综上所述,Linux内存管理通过分段和分页机制,结合物理内存、进程虚拟空间、页错误处理、交换空间和缓冲策略,确保了系统的高效稳定运行。这种复杂的内存管理系统为Linux提供了强大的内存管理和资源调度能力,使其...
此外,Linux还使用了内存池(Slab)技术,针对频繁分配和释放的小对象,提高内存利用率。 2. **虚拟内存**:Linux采用虚拟内存机制,使得每个进程都有独立的4GB(或更大,取决于架构)地址空间。这通过页表(Page ...
Linux内核内存管理还包括了对页替换算法的优化,如最近最少使用(LRU)算法,以及为特定页面类型提供回收策略的机制。内存管理器持续监控系统中内存的使用情况,确保系统性能和稳定性。 以上总结的知识点涵盖了...