高并发内存池-----项目简介、设计⼀个定长的内存池

一.这个项目做的是什么?

        当前项⽬是实现⼀个⾼并发的内存池,他的原型是google的⼀个开源项⽬tcmalloc,tcmalloc全称 Thread-Caching Malloc,即线程缓存的malloc实现了高效的多线程内存管理,⽤于替代系统的内存分配相关的函数(malloc、free)。

        我们这个项目是把tcmalloc最核⼼的框架简化后拿出来,模拟实现出⼀个⾃⼰的⾼并发内存池,⽬的 就是学习tcamlloc的精华,这种⽅式有点类似我们之前学习STL容器的⽅式。但是相⽐STL容器部分, tcmalloc的代码量和复杂度上升了很多。

        另⼀⽅⾯tcmalloc是全球⼤⼚google开源的,可以认为当时顶尖的C++⾼⼿写出来的,他的知名度也 是⾮常⾼的,不少公司都在⽤它,Go语⾔直接⽤它做了⾃⼰内存分配器。

二.项目需要掌握的技能

        这个项⽬会⽤到C/C++、数据结构(链表、哈希桶)、操作系统内存管理、单例模式、多线程、互斥锁 等等⽅⾯的知识。

三.什么是内存池?

1.池化技术

        所谓“池化技术”,就是程序先向系统申请过量的资源,然后⾃⼰管理,以备不时之需。之所以要申请过量的资源,是因为每次申请该资源都有较⼤的开销,不如提前申请好了,这样使⽤时就会变得⾮常快捷,⼤⼤提⾼程序运⾏效率。 在计算机中,有很多使⽤“池”这种技术的地⽅,除了内存池,还有连接池、线程池、对象池等。以服务器上的线程池为例,它的主要思想是:先启动若⼲数量的线程,让它们处于睡眠状态,当接收到客⼾端的请求时,唤醒池中某个睡眠的线程,让它来处理客⼾端的请求,当处理完这个请求,线程⼜进⼊睡眠状态。

2.内存池

        内存池是指程序预先从操作系统申请⼀块⾜够⼤内存,此后,当程序中需要申请内存的时候,不是直 接向操作系统申请,⽽是直接从内存池中获取;同理,当程序释放内存的时候,并不真正将内存返回 给操作系统,⽽是返回内存池。当程序退出(或者特定时间)时,内存池才将之前申请的内存真正释放。

3.内存池主要解决的问题

        内存池主要解决的当然是效率的问题,其次如果作为系统的内存分配器的⻆度,还需要解决⼀下内存 碎⽚的问题。那么什么是内存碎⽚呢? 再需要补充说明的是内存碎⽚分为外碎⽚和内碎⽚,上⾯我们讲的外碎⽚问题。外部碎⽚是⼀些空闲的连续内存区域太⼩,这些内存空间不连续,以⾄于合计的内存⾜够,但是不能满⾜⼀些的内存分配申请需求。内部碎⽚是由于⼀些对⻬的需求,导致分配出去的空间中⼀些内存⽆法被利⽤。内碎⽚问题,我们后⾯项⽬就会看到,那会再进⾏更准确的理解。

四、设计⼀个定长的内存池

        作为程序员(C/C++)我们知道申请内存使⽤的是malloc,malloc其实就是⼀个通⽤的⼤众货,什么场景 下都可以⽤,但是什么场景下都可以⽤就意味着什么场景下都不会有很⾼的性能,下⾯我们就先来设 计⼀个定⻓内存池做个开胃菜,当然这个定⻓内存池在我们后⾯的⾼并发内存池中也是有价值的,所 以学习他⽬的有两层,先熟悉⼀下简单内存池是如何控制的,第⼆他会作为我们后⾯内存池的⼀个基础组件。

 1.windows和Linux下如何直接向堆申请⻚为单位的⼤块内存:

// 直接去堆上按⻚申请空间
 //VirtualAlloc
 //brk和mmap
inline static void* SystemAlloc(size_t kpage)
 {
比特就业课
#ifdef _WIN32
    void* ptr = VirtualAlloc(0, kpage*(1<<12),MEM_COMMIT | MEM_RESERVE, 
PAGE_READWRITE);
 #else
    // linux
下
brk mmap
等
 
#endif
    if (ptr == nullptr)
        throw std::bad_alloc();
    return ptr;
 }

2.定长的内存池实现

#pragma once
#include<iostream>

template<typename T>
class ObjectPool
{
public:
	T* New()
	{
		T* obj = nullptr;

		//优先把换回来的内存块,重复利用
		if (_freeList)
		{
			void* next = *((void**)_freeList);
			obj = (T*)_freeList;
			_freeList = next;
		}
		else
		{
			//剩余内存不够一个对象大小时,则重新开大块空间
			if (_remainBytes < sizeof(T))
			{
				_remainBytes = 128 * 1024;
				_memory = (char*)SystemAlloc(_remainBytes >> 13);
				if (_memory == nullptr)
				{
					throw std::bad_alloc();
				}
			}
			obj = (T*)_memory;
			size_t objSize = sizeof(T) < sizeof(void*) ? sizeof(void*) : sizeof(T);
			_memory += objSize;
			_remainBytes -= objSize;
		}
		new(obj)T;// 定位new,显示调用T的构造函数初始化

		return obj;
	}

	void Delete(T* obj)
	{
		// 显示调用析构函数清理对象
		obj->~T();

		//头插
		*(void**)obj = _freeList;
		_freeList = obj;
	}

private:
	char* _memory = nullptr;//指向大块内存的指针
	size_t _remainBytes = 0;//大块内存在切分过程中剩余的字节数

	void* _freeList = nullptr;//还回来过程中链接的自由链表的头指针
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pipip.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值