### 高并发内存池
借鉴tcmalloc(ThreadCaching Malloc),即线程缓存的malloc,实现了高效的多线程内存管理,用于替代系统的内存分配相关的函数(malloc,free)
池化技术:向系统先申请过量的资源,然后自己管理,以备不时之需,之所以申请过量资源,是因为每次申请资源都有较大的开销,那边不如提前申请好,提高程序运行效率
在计算机中除了内存池,还有连接池,线程池,对象池等,以线程池为例,它的主要思想是,先启动若干数量的线程,让他们处于睡眠状态,当接收到客户端请求时,唤醒某个沉睡的线程,让它处理客户端请求,当处理完请求之后,线程又进入了休眠状态
内存池:程序预先向系统申请一大块足够的内存,此后,当系统需要申请内存的时候,不是直接向操作习题申请,而是向内存池中申请,当释放的时候,不返回给操作系统,而是返回给内存池,当程序退出时,内存池才将申请的内存真正释放
内存池解决问题:
1.主要解决效率问题
2.内存碎片问题
malloc实际就是一个内存池
定长内存池
固定大小的内存申请管理
特定:
性能达到极致
不考虑内存碎片等问题
设计方式:
向内存申请一块足够大的内存块,然后每次申请内存时我们就切出去一小部分拿来使用,
```cpp
//例如
char*_memory=(char*)malloc(128*1024);//一次性直接申请128k的内存,然后申请内存时从这块内存切除对应的大小
int remainBytes=128*1024;//管理剩余的内存数量,单位是字节
```
注意:申请的使用使用char类型的指针(假设为_memory)进行申请,这样方便指针进行后移,例如:如果需要向这块大内存进行申请使用,那么我们就使得 _memory+=sizeof(int),进行后移
![](https://www.writebug.com/myres/static/uploads/2022/7/22/119b611a2b2b1b01685312461a229f76.writebug)
使用时切出一小部分拿出来用:
![](https://www.writebug.com/myres/static/uploads/2022/7/22/42d0b04cbf6306174d1fb3cfc1c52935.writebug)
![](https://www.writebug.com/myres/static/uploads/2022/7/22/b1c15454cf78d07d339d20a6f2ae9459.writebug)
```cpp
//对应伪代码
//假设我们有个T类型的obj指针前来申请对象
obj=_memory;
_memory+=sizeof(T);
_remainBytes-=sizeof(T);
```
当我们释放内存的时候不是直接还给操作系统,而是还给这块大内存,让这块内存被重新使用
![](https://www.writebug.com/myres/static/uploads/2022/7/22/9240198c8f94654024fdb13f88c14a95.writebug)
注意看上面的图:我们让所有还回来的内存像链表链表一样被连接起来,其中_freeList被称为头指针,它的前4个或者8个字节存储下一个内存单元的地址,假设有块内存obj被使用使用之后还回来,那么我们就利用头插法将obj作为头部, _freeList进行前移
![](https://www.writebug.com/myres/static/uploads/2022/7/22/e459f5adc07cc6aa8cd7d2c7460152b2.writebug)
![](https://www.writebug.com/myres/static/uploads/2022/7/22/be3fc171578f310445b79225e38dfed7.writebug)
![](https://www.writebug.com/myres/static/uploads/2022/7/22/d47428fc0d7d2443371732a57d8b28d1.writebug)
```cpp
*(**obj)=_freeList;//注意*(**)obj可以取出obj的前4个或8个字节,然后让他存储下一个地址,即_freeList的地址
_freeList=obj;//让obj重新称为头
```
既然_freeList的前4个或者8个自己保存地址,那么我们必须保证这个obj必须能够存下这些地址,所以我们在申请的时候就要保证obj对象的大小,最起码要能存下一个4/8字节的指针大小,所以前面申请的代码就要进行略微改动
```cpp
//对应伪代码
//假设我们有个T类型的obj指针前来申请对象
obj=_memory;
int objsize=sizeof(T)<sizeof(void*)? sizeof(void*):sizeof(T);//判断这个对象大小是否大于sizoef(void*)
_memory+=objsize;
_remainBytes-=objsize;
```
既然我们已经用一个链表管理每次还回来的内存了,那么这些还回来的内存改怎么办呢?答案是重复利用,所以当我们申请内存时,如果_freeList不为空,就说明当前已经有还回来的内存了,那么我们优先使用这块内存来进行申请,节约空间
![](https://www.writebug.com/myres/static/uploads/2022/7/22/e4d8d73a28facbd0ef4bad180fa770c3.writebug)
![](https://www.writebug.com/myres/static/uploads/2022/7/22/d23907b538096205d917b672cfc5d002.writebug)
![](https://www.writebug.com/myres/static/uploads/2022/7/22/fcd9b242aa39c0b0a2250855cdb06166.writebug)
```cpp
//说明有还回来的内存,重复利用
if(_freeList)
{
void*next=*(void**)_freeList;//保存_freeList保存的下一个位置的地址,然后让_freeList指向下一个位置
obj=_freeList;//将当前位置赋值给obj
_freeList=next;//_feeList指向下一个位置
return obj;//返回这块内存进行使用
}
```
申请内存的完整代码
```cpp
T*New()
{
//优先把还回来的内存块对象重复利用
T*_obj==nullptr;
//说明有还回来的内存,重复利用
if(_freeList)
{
void*next=*(void**)_freeList;
obj=_freeList;
_freeList=next;
return obj;
}
//剩余内存不够一个对象大小时,重新开一个大块空间
if(_remainBytes<sizeof(T))
{
_memory=(char*)malloc(128*1024);
_remainBytes=128*1024;
if(_memory==nullptr)
{
throw bad_alloc();
}
}
_obj=(T*)_memory;
size_t objsize=sizeof(T)<sizeof(void*)? sizeof(void*):sizeof(T);
_memory+=objsize;
_remainBytes-=objsize;
//定位new,显示调用T的构造函数初始阿虎
new(obj) T;
return _obj;
}
```
释放当前内存
```cpp
void Delete(T* obj)
{
//显示调用T的析构函数
obj->~T();
if (obj != nullptr)
{
*(void**)obj = _freeList;
_freeList = obj;
}
}
```
上面的代码我们使用malloc,下面我们可以将malloc转换成系统调用函数申请空间,默认以页为单位进行内存申请,一页为4/8k,我们将所有的malloc函数替换为SystemAlloc函数即可,当然,这样做并不能提升效率,但是可以全部使用系统调用
```
inline static void* SystemAlloc(size_t kpage)
{
# ifdef _WIN32
//windows平台下申请内存
void* ptr = VirtualAlloc(0, kpage * 8 * 1024, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
# else
//Linux下使用brk,mmap等
# endif
if (ptr == nullptr)
{
throw std::bad_alloc();
}
return ptr;
}
```
完整代码如下所示:
```cpp
# pragma once
# include<iostream>
# include<vector>
# include<Windows.h>
# include<time.h>
using std::cout;
using std::endl;
//向系统申请内存,以页为单位进行申请
inline static void* SystemAlloc(size_t kpage)
{
# ifdef _WIN32
//windows平台下申请内存
void* ptr = VirtualAlloc(0, kpage * 8 * 1024, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
# else
//Linux下使用brk,mmap等
# endif
if (ptr == nullptr)
{
throw std::bad_alloc();
}
return ptr;
}
template <class T>
class ObjectPool {
public:
//申请内存
T* New()
{
T* obj = nullptr;
//首先向_freeList中进行申请
if (_freeList)
{
void* next = *((void**)_freeList);
obj =(T*)_freeList;
_freeList = next;
}
return obj;
//判断剩余内存是否足够,如果不足够就申请一大块内存进行读取
if (sizeof(T) > _remainBytes)
{
_memory = (char*)SystemAlloc(16);
_remainBytes = 128 * 1024;
if (_memory == nullptr)
{
throw std::bad_alloc();
}
}
obj = (T*)_memory;
new(obj)T;
size_t objsize = sizeof(T) < sizeof(void*) ? sizeof(void*) : sizeof
没有合适的资源?快使用搜索试试~ 我知道了~
基于C++研究高并发内存池【100011812】
共32个文件
tlog:6个
h:3个
pdb:2个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 140 浏览量
2023-04-11
16:17:31
上传
评论 1
收藏 20.01MB ZIP 举报
温馨提示
内存池:程序预先向系统申请一大块足够的内存,此后,当系统需要申请内存的时候,不是直接向操作习题申请,而是向内存池中申请,当释放的时候,不返回给操作系统,而是返回给内存池,当程序退出时,内存池才将申请的内存真正释放
资源推荐
资源详情
资源评论
收起资源包目录
100011812-基于C++研究高并发内存池.zip (32个子文件)
concurrency_memory_pool
LICENSE 1KB
ConcurrencyMemoryPool
ObjectPool.h 2KB
ThreadCache.h 138B
ConcurrencyMemoryPool.vcxproj.user 165B
Common.h 615B
ConcurrencyMemoryPool.sln 1KB
.gitattributes 42B
ConcurrencyMemoryPool.vcxproj 7KB
.vs
ConcurrencyMemoryPool
v16
.suo 20KB
v17
Browse.VC.db 15.66MB
.suo 34KB
ipch
AutoPCH
fd89271381474615
OBJECTPOOL.ipch 35.38MB
77741e23ee54f2c8
MAIN.ipch 38.38MB
x64
Debug
vc143.pdb 500KB
ConcurrencyMemoryPool.exe.recipe 340B
ConcurrencyMemoryPool.log 157B
ConcurrencyMemoryPool.ilk 1011KB
ConcurrencyMemoryPool.pdb 2.5MB
ConcurrencyMemoryPool.vcxproj.FileListAbsolute.txt 192B
vc143.idb 371KB
ConcurrencyMemoryPool.exe 95KB
Concurre.6a43f0b4.tlog
CL.write.1.tlog 676B
ConcurrencyMemoryPool.lastbuildstate 199B
CL.command.1.tlog 2KB
link.command.1.tlog 3KB
link.read.1.tlog 3KB
link.write.1.tlog 794B
CL.read.1.tlog 41KB
Main.obj 277KB
ConcurrencyMemoryPool.vcxproj.filters 1KB
Main.cpp 49B
README.md 32KB
共 32 条
- 1
资源评论
神仙别闹
- 粉丝: 2680
- 资源: 7667
下载权益
C知道特权
VIP文章
课程特权
开通VIP
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 基于C++实现的全景图像拼接源码(课程设计)
- 基于SIFT特征点提取和RASIC算法实现全景图像拼接python源码+文档说明+界面截图+详细注释(95分以上课程大作业)
- 基于matlab实现眼部判别的疲劳检测系统+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
- 基于Matlab的异常姿势识别系统+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
- 隐藏文件展示工具,用来展示被病毒隐藏的文件
- 基于Matlab的图像分割系统+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
- 基于MATLAB指纹门禁GUI设计源码+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
- 基于Matlab的仪表指数识别系统霍夫曼变换+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
- 基于MATLAB 的霍夫曼变换答题卡识别带GUI界面+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
- 基于MATLAB 疲劳驾驶检测专识别GUI源码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功