内存池1
概述:
对于某一个具体的应用程序来说,适合自身特定的内存分配释放模式的自定义内存池可以获得更好的性能。
内存池(Memory Pool)是一种内存分配方式。通常我们习惯直接使用new、malloc等API申请内存,这样做
的缺点在于所申请内存块的大小不定,当频繁使用时会造成大量的内存碎片并进而降低性能。降低内存的利用率,
所以,将内存配置问题交给底层的内存池去处理,是一个不错的选择。
内存池的优点
内存池则是在真正使用内存之前,预先申请分配一定数量、大小相等(一般情况下)的内存块留作备用。当有新的内存需求时,
就从内存池中分出一部分内存块,若内存块不够再继续申请新的内存。这样做的一个显著优点是,使得内存分配效率得到提升。
实现1——io_buf
首先创建⼀个 io_buf 类,主要⽤来封装基本的buffffer结构。然后⽤⼀个 buf_pool 来管理全部
的buffer集合
io_buf.h文件
//定义⼀个 buffer存放数据的结构
class io_buf {
public:
//构造,创建⼀个io_buf对象
io_buf(int size);
//清空数据
void clear();
//将已经处理过的数据,清空,将未处理的数据提前⾄数据⾸地址
void adjust();
//将其他io_buf对象数据考本到⾃⼰中
void copy(const io_buf *other);
//处理⻓度为len的数据,移动head和修正length void pop(int len);
//如果存在多个buffer,是采⽤链表的形式链接起来
io_buf *next;
//当前buffer的缓存容量⼤⼩
int capacity;
//当前buffer有效数据⻓度
int length;
//未处理数据的头部位置索引
int head;
//当前io_buf所保存的数据地址
char *data;
};
io_buf的实现
io_buf.cpp文件
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include "io_buf.h"
//构造,创建⼀个io_buf对象
io_buf::io_buf(int size):
capacity(size),
length(0),
head(0),
next(NULL)
{
data = new char[size];
assert(data);
}
//清空数据
void io_buf::clear()
{
length = head = 0;
}
//将已经处理过的数据,清空,将未处理的数据提前⾄数据⾸地址
void io_buf::adjust()
{
if (head != 0)
{
if (length != 0)
{
memmove(data, data+head, length);
}
head = 0;
}
}
//将其他io_buf对象数据考本到⾃⼰中
void io_buf::copy(const io_buf *other)
{
memcpy(data, other->data + other->head, other->length);
head = 0;
length = other->length;
}
//处理⻓度为len的数据,移动head和修正length
void io_buf::pop(int len)
{
length -= len;
head += len;
}
总结:
这⾥主要要注意io_buf的两个索引值length和head,⼀个是当前buffer的有效内存⻓度,
haed则为可⽤的有效⻓度⾸数据位置。 capacity是io_buf的总容量空间⼤⼩。所以每次 pop()
则是弹出已经处理了多少,那么buffer剩下的内存就接下来需要处理的。然⽽ adjust() 则是从
新重置io_buf,将所有数据都重新变成未处理状态。clear() 则是将length和head清0,这⾥没有
提供 delete 真是删除物理内存的⽅法,因为这⾥的buffer设计是不需要清理的,接下来是⽤⼀个
buf_pool 来管理全部未被使⽤的 io_buf 集合。⽽且 buf_pool 的管理的内存是程序开始预开辟的,
不会做清理⼯作。