MyDog--内存--pool

  • 首先有个能创建固定长度的内存块的池
/// <summary>
/// 申请固定大小的内存池
/// 内部使用类,不考虑那些安全隐患的地方
/// 比如不用考虑归还的内存是否长度对应等
/// </summary>
class MyDogPoolFixSize
{
	uint16 mNum;
	int32 fixsize;
	void* mPool;
public:
	/// <summary>
	/// fixs为固定内存大小
	/// 最小为sizeof(void*) + 1
	/// </summary>
	MyDogPoolFixSize(int32 fixs);
	~MyDogPoolFixSize();
	/// <summary>
	/// 创建cnt个内存放入池里
	/// </summary>
	void create(int32 cnt = 1);
	/// <summary>
	/// 申请内存
	/// </summary>
	vptr apply();
	/// <summary>
	/// 回收内存
	/// </summary>
	void free(vptr data);
	/// <summary>
	/// releasePro是每次release时的释放比例(百分比)
	/// </summary>
	void release(int8 releasePro = 60);
};

在这个基础上,对这些池进行管理,于是就有了


#pragma pack(push)
#pragma pack(1)
	struct PoolConfItem {
		uint32 fixsize;//用于MyDogPoolFixSize初始化
		uint8 releasePro;//每次release时的释放比例(百分比)
		uint16 releaseCD;//释放cd 秒
	};
#pragma pack(pop)
	struct BuffItem {
		vptr data;
		uint8 index;//max_uint8表示超出配置
		BuffItem():data(null),index(max_uint8){}
		BuffItem(vptr d,int i):data(d),index(i){}
		~BuffItem() { data = nullptr; }
	};

	class ReadBuff;
	/// <summary>
	/// 管理所有的MyDogPoolFixSize
	/// 由于主要服务于属性集,所以可以在编译前知道各种属性集大小,从而得出PoolConfItem
	/// </summary>
	class MyDogPoolMgr {
		PoolConfItem* pool_items;
		MyDogPoolFixSize** mPool;
		uint8 mLeng;
	public:
		MyDogPoolMgr(ReadBuff& rb);
		~MyDogPoolMgr();
		/// <summary>
		/// 根据大小,获取index
		/// </summary>
		uint8 s2index(uint32 s, uint32* rs=null);
		/// <summary>
		/// 获取配置最大index
		/// </summary>
		inline uint8 maxindex() {
			return mLeng - 1;
		}
		/// <summary>
		/// 根据index申请一段内存
		/// </summary>
		BuffItem applyByid(uint8 index);
		/// <summary>
		/// 根据大小申请一段内存
		/// </summary>
		BuffItem applyBysize(uint32 s);
		/// <summary>
		/// 归还内存
		/// </summary>
		void replay(BuffItem& item);
	};

这样设计,关键还是这句话:

由于主要服务于属性集,所以可以在编译前知道各种属性集大小,从而得出PoolConfItem

配置内容,可结合TCMalloc小内存的参数,以及由工具分析出来的配置

s2index函数是很有用的,rs返回真实内存块大小

  • 下面的类就是对这个pool的直接使用
/// <summary>
/// 非连续内存的dispbuff
/// </summary>
class WriteDispBuff {
	vector<BuffItem> vec;
	uint8 mApplyid;//内存不够时,固定申请
	uint32 mFixsize;//每个块的实际大小
	uint32 mLeft;//当前写入块剩余长度
	dptr getdata();
public:
	WriteDispBuff(uint32 s = 128);
	~WriteDispBuff();
	/// <summary>
	/// 写入内存
	/// </summary>
	template<typename T> WriteDispBuff& operator<<(const T& t) {
		int32 s = sizeof(T);
		uint32 off = 0;
		while (s>0) {
			dptr rdata = getdata();
			if (mLeft >= s) {
				memcpy(rdata, (dptr)(&t) + off, s);
				mLeft -= s;
				break;
			}
			else {
				memcpy(rdata,(dptr)(&t) + off, mLeft);
				mLeft = 0;
				off += mLeft;
				s -= mLeft;
			}
		}			
		return *this;
	}
	/// <summary>
	/// 写入内存
	/// </summary>
	WriteDispBuff& writeBuff(dptr data,uint32 s);
	/// <summary>
	/// fixs每块的大小
	/// useBlock用了几块
	/// left最后一块的使用长度
	/// </summary>
	inline void getInfo(uint32& fixs, uint16& useBlock, uint32& leng) {
		fixs = mFixsize;
		useBlock = vec.size();
		leng = mFixsize - mLeft;
	}
	/// <summary>
	/// 读取内存,和getInfo配合使用
	/// </summary>
	inline dptr readData(uint16 index) {
		return (dptr)vec[index].data;
	}
};

具体的cpp看源码吧...

  • 非连续内存的dispbuff,这个也是很有用的东西,它不需要知道要写入的数据有多大.序列化数据就很管用.另外可以通过getInfo和readData接口遍历数据.


MyDog--前言和目录(附源码链接)-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值