问题描述:
c++中,每次使用malloc,realloc,new 等会进入内核态,频繁的陷入内核态会消耗非常多的资源,而且每次操作指针容易出现数组越界等非法操作.作者模仿了linux的内存分配,写了一个c++的内存管理器
问题抽象:
把整个问题想象成银行贷款,银行抽象为操作系统,贷款的人抽象为线程,贷款抽象为内存申请,还款抽象为内存释放,当很多人同时向银行贷款几百块,又同时归还几百块,会使得银行非常忙碌.
为了解决这个问题,我们的办法是,一次性向银行贷款一大笔钱,然后去做事情,并在规定的还款日期全归还.当我们手中的钱,还不够的时候,再向银行贷款.
计算机术语描述:
管理器初始化时候,向操作系统申请几大块内存,当这些内存不足以存储信息的时候,向内存申请新的内存,线程可以通过管理器提供的函数,申请得到内存,管理器存储分配信息与释放,通过查询信息,得到碎片内存信息,通过分配算法,查询到最佳分配方案
内存分配算法:保存所有的释放的空间碎片信息,对其进行整理,把连续的空间碎片信息合并,每次分配的时候,查询那种碎片更契合分配要求(最佳分配就是碎片长度等于需求长度)
设计思想:
分配几个大块儿内存,每块儿内存分别存储每种数据,并生成该种类型数据的碎片表信息和活跃内存信息表,通过不同种类信息,能更快定位到需要查找的内存信息(类似于索引表查询)
数据结构分析:
需要注册数据结构类型包含:
name:方便用户查询
id:方便计算机查询
szof:单个数据的长度
now_count:当前数据的总长度
add_count:当内存不足以存储的时候,增加的长度
addrs:每个内存块的首地址合集
基本内存信息:
addr:保存内存块儿的首地址
cout:保存内存块儿的长度
扩展内存信息:
id:内存类型id
msgs:基本内存信息
查询内存信息:
name:数据类型名字
szof:单个该数据类型的长度
posi:该地址在内存块儿的偏离位置
cout:整个内存块儿大小
数据结构定义:
#ifdef OPERATOR_SIZE_64 //64位操作系统
#pragma pack(push)
#pragma pack(8)//8字节对齐
typedef struct MemoryHeadMsg
{
char mhm_name[M_MAX_NAME_SIZE];
uint mhm_id;
uint mhm_szof;
MVector<byte*> *mhm_addr;
ulong mhm_now_count;
ulong mhm_add_count;
}MEMORYHEADMSG;
typedef struct MemoryMsg
{
byte* mm_addr;
uint count;
}MEMORYMSG;
typedef struct MemoryMsgEx
{
uint mhm_id;
MVector<MemoryMsg> *mme_msgs;
}MEMORYMSGEX;
typedef struct MemoryMsgDetailUnit
{
char name[M_MAX_NAME_SIZE];
uint szof;
int posi;
ulong count;
}MEMORYMSGDETAILUNIT;
#pragma pack(pop)
#endif // OPERATOR_SIZE_64
管理器api函数定义:
int M_regis_struct(const char* name, uint szof, ulong count);//注册数据类型
int M_find_id(con