内存池:简单的内存池的实现

2023-05-16

转载自:http://blog.sina.com.cn/s/blog_46ed82810100ch8h.html

当频繁地用malloc申请内存,然后再用free释放内存时,会存在两个主要问题。第一个问题是频繁的分配释放内存可能导致系统内存碎片过多;第二个问题是分配释放内存花费的时间可能比较多(这个问题不太明显)。这个时候我们就可以考虑使用内存池了。

最朴素的内存池思想就是,首先你向系统申请一块很大的内存(这块内存因为很大,以致于我们常称它为memory pool),然后你在上面实现类似于malloc和free等操作。当你需要分配内存时,你用自己的类malloc函数从内存池上取一小块给使用者(后文称之为小内存块),当用类free函数释放从内存池上取得的内存时,这个小内存块也并不归还给系统,而只是还给内存池。

最近写telnet还原程序,写了个简易内存池,和大家分享下。

这个内存池提供这样的功能:i)提供类malloc函数mem_alloc从内存池上获取固定大小的内存,提供类free函数mem_free释放内存到内存池中;ii)内存池初始大小为某个固定大小(BUF_SIZE)的n倍,当内存池中的内存不够用时,内存池能以一定步长增长直到无系统内存。

要实现这些功能,首先应该用一个数据结构(mem_node_t)将内存池中的各个小内存块挂起来;然后为了使内存池能够以一定步长增长,我们要能分配多个大的内存块(即多个小内存池),为了能顺利的管理各个大的内存块,需要一个数据结构(mem_block_t)来记录这些信息;最后,内存池的当前状态(包括可分配的空闲链表,空闲的小内存块的个数等)是我们感兴趣的东西,所以用数据结构(mem_pool_t)来记录。

typedef union _mem_node
{
union _mem_node *next;
char buf[BUF_SIZE];
}mem_node_t, *pmem_node_t;

typedef struct _mem_block
{
mem_node_t *node_head;
mem_node_t *node_tail;
int node_cnt;
struct _mem_block *next;
}mem_block_t, *pmem_block_t;

typedef struct _mem_pool
{
mem_block_t *block_head;
mem_block_t *block_tail;
mem_node_t *free_head;
int block_cnt;
int free_cnt;
int base;
int step;
}mem_pool_t, *pmem_pool_t;

然后提供了一些操作函数:mem_pool_init用来初始化内存池;mem_pool_destroy用来释放内存池,将内存池所占空间归还系统;print_mem_pool_info用来打印内存池的信息;mem_alloc,用来从内存池上分配小内存块;mem_free,将小内存块归还给内存池。

mem_alloc和mem_free操作的就是内存池的空闲链表,前者从空闲链表取一个结点,后者将一个结点插入空闲链表。而这个空闲链表是由mem_pool_init初始化的,而且当内存池增长时,即增加新的大内存块时,我们将大内存块上的小内存块也挂接到这个空闲链表上来。需要注意的是小内存块的数据结构用了联合,这是因为小内存块要么是挂接在空闲链表上,要么是分配给了用户,必居且只能居这两种状态之一,这个数据结构可根据需求适当改进。

在码代码之前,要补充说明的是,不少内存池都提供了分配不同大小的内存块的功能,将多个不同大小的本内存池链接起来也可实现这些功能,改动是比较容易的^_^

最后,本内存池在vc6下验证当频繁分配释放100字节大小的内存时,本内存池效率约是直接malloc和free的10倍,当分配大”湫∈保时扔兴档停狈峙浯笮≡龃笫保时扔兴撸峙1000字节大小的内存时,效率比约为100。

代码。



#ifndef _MEM_POOL_H_

#define _MEM_POOL_H_

#define BUF_SIZE 100

#define BASE_COUNT 10000

#define STEP_COUNT 1000

typedef union _mem_node

{

union _mem_node *next;
char buf[BUF_SIZE];
}mem_node_t, *pmem_node_t;

typedef struct _mem_block
{
mem_node_t *node_head;
mem_node_t *node_tail;
int node_cnt;
struct _mem_block *next;
}mem_block_t, *pmem_block_t;

typedef struct _mem_pool
{
mem_block_t *block_head;
mem_block_t *block_tail;
mem_node_t *free_head;
int block_cnt;
int free_cnt;
int base;
int step;
}mem_pool_t, *pmem_pool_t;

int mem_pool_init(int base, int step);

void mem_pool_destroy(void);

void print_mem_pool_info(void);

void *mem_alloc(void);

void mem_free(void *ptr);

#endif

/************************mem_pool.c************************

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

内存池:简单的内存池的实现 的相关文章

随机推荐

  • 解决Spring AOP 事务 配置 失效原因

    采用AOP配置声明式事务有5种方式 xff0c 下面只说关于采用TransactionInterceptor事务拦截器的方式 xff0c 配置程序如下 xff1a transactionManager xff1a lt bean id 61
  • 兼容chrome与firefox使用offsetWidth得到不同值的问题

    Ext3 x Ext MessageBox alert 在chrome与firefox显示的宽度不一致问题 究其原因是因为msgEl getWidth 得到的值不一致导致的 修正宽度应方法 xff1a chrome xff1a rect 6
  • 内嵌标志表达式

    对应的内嵌标志表达式是 i xff0c 它有四种形式 xff1a 1 xff0c i 2 xff0c i 3 xff0c i X 4 xff0c i X 不带有 的是开标志 xff0c 带有 的是关标志 把上面的代码改成这样 xff1a J
  • LoadRunner 90 Percent设置

    90 Percent 的设置 xff1a tools xff08 工具 xff09 options xff08 选项 xff09 General选项卡最下面有个Summary Report
  • 高通8155平台YOCTO CMAKE 编译问题解决方法

    硬件平台 xff1a 高通8155 软件平台 xff1a yocoto linux 43 ubuntu16 04 最近开始接触8155平台 xff0c 发现编译阶段出现cmake编译失败 xff0c 网上搜了一下没有相关的解决方案 xff0
  • 解决Ext.Grid单元格不能被选择

    ExtJs3 x版本 xff0c Ext grid GridPanel单元格数据不能被选择 xff0c 在不同浏览器环境下的解决方法不同 xff1a 1 Chrome Safari xff1a ext webkit x grid panel
  • Hadoop-1.2 单机部署

    准备相关资源环境 运行环境工具 Linux Centos 6 3 JDK 1 7 0 51 SSH Secure Shell 1 下载Hadoop1 2 http mirrors cnnic cn apache hadoop common
  • Hbase-0.94.19 单机部署

    准备相关环境 运行环境工具 Linux Centos 6 3 JDK 1 7 0 60 Hadoop 1 2 1 SSH Secure Shell Hbase需建立在Hadoop环境之上运行 xff0c 参考Hadoop1 2 1单机部署
  • Android Beam:引领未来的NFC数据交换

    还记得吗 xff1f 惠普曾经将TouchPad平板电脑与Pre 3接触就实现了网页交换 也许那时大家都在想 xff1a 太酷啦 xff0c 要是我有TouchPad和pre3就好了 昨天新发布的Android 4 0Ice Cream S
  • TabHost设置选项卡被选中时背景颜色

    TabHost设置选项卡被选中时背景颜色 xff0c 通过给每个选项卡的Button设置背景样式实现 文件名 xff1a bottom btn first bg billboard xml 内容如下 xff1a lt xml version
  • 如何从文件中检索关键字出现的次数

    首先得到文件的完整路径 然后从流中读取每个字符 如果读出的字符和关键字的第一个字符相同 xff0c 则按照关键字长度读取相同个数的字符 分别判断是否相同 xff0c 若有一个不相同则break 否则计数器count 43 43 xff0c
  • 被其他Activity覆盖不触发onStop的情况

    被其他Activity覆盖不触发onStop的情况 xff1a 一般情况下当一个Activity被其他Activity覆盖时 被覆盖的Activity都会调用onStop xff08 xff09 方法 但是有两种情况除外 一个是上层Acti
  • 如何找到一个数组中第三大数字并输出它所在的位置

    面试题 如何找到一个数组中第三大数字并输出它所在的位置 延伸问题 xff1a 如何找到一个数组中第N大元素并输出它所在的位置 br public class FindThirdLarge br public static void getT
  • 输出出一个数组中出现次数最多的数字以及它出现的次数

    查找一个数组中出现次数最多的数字以及它出现的次数并输出出来 br public class FindMostAppearTime br public static void getMostAppearNumber int array br
  • Activity的四种启动模式

    color 61 red Standard color 默认启动模式 标准模式 每次启动Activity都会创建新的Activity对象实例 color 61 red SingleInstance color 只要在当前应用中启动过该Act
  • 可装载内核模块-Loadable Kernel Module (LKM)

    0x01 可装载模块分类 设备驱动 文件系统 系统调用 0x02 版本检查 Linux 的迅速发展致使相邻版本的内核之间亦存在较大的差异 xff0c 即在版本补丁号 xff08 Patch Level xff0c 即内核版本号的第四位数 x
  • couldn't load font "宋体 9", falling back to "Sans 9", expect ugly output.

    Windows下使用Ruby GNOME2写GUI时 xff0c 会报以下错误 xff1a Pango WARNING couldn 39 t load font 34 宋体 9 34 falling back to 34 Sans 9 3
  • TCP/IP数据包结构详解

    关键词 TCP IP 数据包 结构 详解 网络 协议 一般来说 xff0c 网络编程我们只需要调用一些封装好的函数或者组件就能完成大部分的工作 xff0c 但是一些特殊的情况下 xff0c 就需要深入的理解 网络数据包的结构 xff0c 以
  • Ubuntu 网络配制方法(同事的blog,拿来备份.)

    etc network interfaces 打开后里面可设置DHCP或手动设置静态ip 前面auto eth0 xff0c 让网卡开机自动挂载 1 以DHCP方式配置网卡 编辑文件 etc network interfaces sudo
  • 内存池:简单的内存池的实现

    转载自 xff1a http blog sina com cn s blog 46ed82810100ch8h html 当频繁地用malloc申请内存 xff0c 然后再用free释放内存时 xff0c 会存在两个主要问题 第一个问题是频