首页 > 编程知识 正文

内存堆栈结构图,内存池使用的场景

时间:2023-05-03 22:54:25 阅读:163184 作者:143

概念内存池是指在程序启动时,预先向堆申请一部分内存,传递给一个管理对象。 程序运行中,必要时向管理对象“借”,不必要时向管理对象“还”。

原理很简单,关键是怎样才能高效地“借”、“还”。

实例场景在C/S服务器上需要频繁地发送和接收包。 如果数据包的内存采用原来的new-delete模式,服务器的性能将大幅下降,所以我们考虑使用内存池技术。

这个例子有几个硬条件。

1 .由于可以预测数据包的最大长度,所以暂时将内存池内的块的大小定为1024。

2、内存池适合多线程情况。 也就是说,可以同时有多人“借”同一空闲块。

设计构想一、内存存放结构

二、第一次“借”

检查内存池,发现块1是空的。 可以“借”。 标记块1是“借来的”,记录当时的位置(1,1 )。 然后,“借我方框1”。

三、连续几次“借”出,中途可能有几次归“还”

“借”的时候都是根据上次“借”的时候打出的位置遍历后面,运气不好的话遍历到最后。 当然,多线程可能会在中途返还几次,但也不妨碍出借。 返还时,标记块的状态可以是“空”。 状态为bool值,如果是一读一读,则不需要锁定。 怎么说的时候读一遍? 借的时候需要锁门(一读)。 借给你之后,只有能借的人才能写)。

四、遍历到末尾了

在借还过程中,总是会发生这样的事情。 当前位置(3,1 )中,后面的块都被标记为“借用”。 很明显,像这样直接遍历到末尾。 后面没有数据。 只需看看从头(3,1 )部分的数据块中是否有空闲空间。 幸运的是,(1,2 )我有空了。

五、没有空闲的块了

从当前位置向后遍历时,没有空闲块。 而且,即使从头遍历到当前位置,也没有空块。 说明:需要将新内存添加到内存池。 然后,直接回到刚申请内存的第一个块。

不管你说什么,这只是众多构想之一。 虽然有瑕疵,但是想不出更好的方法。 麻烦的是需要考虑多线程。 有多线程的话就必须上锁。 上锁是一种变相的单线程,会影响效率。 这里只是给借来的存储器上锁了,存储器就不用上锁了。 先把这个写几个实例看看,比较一下哪个方法更有效率。

代码采用模板类,通用性强。 编译通过了,但没有使用过。

templateclass Tstruct sBlock{ T t; //放在头上,指针有力,便于转换char flag可用标志,0:可用1:不可用}; # ifndef mempool _ h # define mempool _ h # include vector # includemutexusingnamespacestd; templateclasstclassmempool { public : mempool () :m_curbuffindex(0),m_curBlockIndex(0), m _ basebuffcous m _ baseblockcount (0) {} ~MemPool ) (boolinit ) unsignedintbuffcount,unsigned int blockCount ) m _ basedint addBuff (; 返回真; } T* mallocT () lock_guardmutexlk ) m_mt ); //向后for (遍历); m_curBuffIndex m_buffs.size (; m_curbuffindex({for ); m _ curblockindexm _ baseblockcount; m_curBlockIndex(if(m_buffs ) m_curbuffindex ) (m_curblockindex ).flag==0) ) m _ buffs m _ cucurbuffff } } m_curBlockIndex=0; (//前方int tempIndex=m_curBuffIndex; for(m_curbuffindex=0; m_curBuffIndex tempIndex; m_curbuffindex({for ); m _ curblockindexm _ baseblockcount; m_curBlockIndex(if(m_buffs ) m_curbuffindex ) (m_curblockindex ).flag==0) ) m _ buffs m _ cucurbuffff } } m_curBlockIndex=0; //因为没有空闲存储器块,所以申请新的存储器int tempSize=m_buffs.size (; addBuff (; m_curBuffIndex=tempSize; m _ buffs [ m _ curbuffindex ] [ m _ curblockindex ].flag=1; return m _ buffs [ m _ curbuffindex ] [ m _ curblockindex ]; }voidfreet(t*p ) ) memset ) p,0,sizeof(T ) t ); blockt*PBK=(sblockt* ) p; pbk-flag=0; //原子操作,一读即可写,无需加锁(}private: void addBuff ) ) for(intI=0; i m_baseBuffCount; I ) intsize=sizeof(sblockt ) * m_baseBlockCount; sblockt*pblocks=(sblockt* ) malloc ) size; memset(pblocks,0,size ); m_buffs.push_back(pblocks; } private : vectorsblockt * m _ buffs; unsigned int m_curBuffIndex; //当前正在使用的大内存索引unsigned int m_curBlockIndex; //当前正在使用的块索引unsigned int m_baseBuffCount; //大内存基数,每次大内存数unsigned int m_baseBlockCount;//包含在一个大容量存储器中的块mutex m_mt的数量; (; #endif //MEMPOOL_H

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。