.H内容如下:

  1. /*********************************************************
  2. 在一些不确定内存总占用量的情形下,频繁的使用new申请内存,再通过链表
  3. 进行索引似乎是很常规的做法。自然,也很难做到随机定位。
  4. 下面的内存池类是用二层索引表来对内存进行大块划分,任何一个块均只需索
  5. 引3次即可定位。
  6. 索引数量,每索引块的分配单元数量,以及分配单元的字节长度均需为2的整数
  7. 次幂(为了运算时的效率)
  8. //by:www.datahf.net zhangyu(zhangyu.blog.51cto.com)
  9. *********************************************************/
  10. class MemTable
  11. {
  12. public:
  13. MemTable(void);
  14. public:
  15. ~MemTable(void);
  16. public:
  17. void CREATE(MemTableIn *in_m);
  18. void DEL();
  19. LPSTR NEW();//分配一个unit
  20. LPSTR NEW_CONTINUEOUS(UINT n);//用于连续分配若干个unit
  21. UINT NEW(UINT n); //用于可碎片方式分配若干个unit
  22. LPSTR GET(UINT n);//用来获得第n个分配的指针地址
  23. int get_totle_unitnum();
  24. public:
  25. MemTableIn in;
  26. LPSTR **pDouble_Indirect;
  27. LPSTR lpBitmap;
  28. LPSTR *pIndirect;
  29. LPSTR m_lpFirstFree;
  30. int nFree[3];//0表示二级索引的自由,1表示1级索引的自由,2表示块自由索引号
  31. INT32 m_EndBlkUseredUnits;
  32. int m_Vblkbytes;
  33. UINT m_UnitTotalNum;
  34. UINT m_log2Rindexs,m_log2Runits,m_log2Rbitmap,m_log2Lindexs,m_log2Lunits,m_log2Lbitmap;
  35. UINT m_log2UnitBytes;
  36. UINT m_index2ID,m_index1ID,m_UnitID;
  37. };

.CPP内容如下:

  1. /**
  2. * ffs - Find the first set bit in an int
  3. * @x:
  4. *
  5. * Description...用来统计一个整型数据的最高为1的位,后面有多少位。
  6. *换个说法:从最高位开始找1,找到1后,看这个二进制数据1000....000是2的几次方
  7. *
  8. * Returns:
  9. */
  10. int ffs(int x)
  11. {
  12. int r = 1;
  13. if (!x)
  14. return 0;
  15. if (!(x & 0xffff)) {
  16. x >>= 16;
  17. r += 16;
  18. }
  19. if (!(x & 0xff)) {
  20. x >>= 8;
  21. r += 8;
  22. }
  23. if (!(x & 0xf)) {
  24. x >>= 4;
  25. r += 4;
  26. }
  27. if (!(x & 3)) {
  28. x >>= 2;
  29. r += 2;
  30. }
  31. if (!(x & 1)) {
  32. x >>= 1;
  33. r += 1;
  34. }
  35. return r;
  36. }
  37. LPSTR MemTree::GET(MemTreeHead *pHead,UINT n)
  38. {
  39. int t;
  40. LPSTR lpt;
  41. int i,ii;
  42. //判断是否直接存储
  43. if(n<m.rootDirectUnitNum)
  44. return pHead->lpRootUnit + n*m.Vsizeof;
  45. else
  46. t=n-m.rootDirectUnitNum;
  47. for(i=1;i<DEEP;i++)
  48. {
  49. if(t<TBT[i][0])
  50. break;
  51. t-=TBT[i][0];
  52. }
  53. //i便是深度,t是深度内的n
  54. lpt=pHead->pROOT_INDEX[i-1];
  55. int D;
  56. for(ii=1;ii<i;ii++)
  57. {
  58. D=t /TBT[i][ii];
  59. t=t % TBT[i][ii];
  60. lpt=*(LPSTR*)(lpt+sizeof(LPSTR)*D);
  61. }
  62. return (lpt +   t*m.Vsizeof);
  63. }
  64. MemTable::MemTable(void)
  65. {
  66. }
  67. MemTable::~MemTable(void)
  68. {
  69. //释放所有空间
  70. for(int i=0;i<in.nIndexNum;i++)
  71. {
  72. LPSTR *pp=pDouble_Indirect[i];
  73. if(pp==NULL)
  74. break;
  75. for(int ii=0;ii<in.nIndexNum;ii++)
  76. {
  77. LPSTR p=pp[ii];
  78. if(p==NULL)
  79. break;
  80. else
  81. delete [] p;
  82. }
  83. delete [] pp;
  84. }
  85. delete [] pDouble_Indirect;
  86. }
  87. void MemTable::CREATE(MemTableIn *in_m)
  88. {
  89. //1、初始化一些参考块
  90. memset(&in,0,sizeof(in));
  91. in=*in_m;
  92. m_UnitTotalNum=0;
  93. nFree[0]=nFree[1]=nFree[2]=0;
  94. m_Vblkbytes= in.nUnitBytes *in.nUnitPerIndex;
  95. m_log2Runits=ffs(in.nUnitPerIndex)-1;
  96. m_log2Rindexs=ffs(in.nIndexNum)-1;
  97. m_log2UnitBytes=ffs(in.nUnitBytes)-1;
  98. m_log2Lindexs=sizeof(UINT)*8-m_log2Rindexs;
  99. m_log2Lunits=sizeof(UINT)*8-m_log2Runits;
  100. //2、初始化二级索引表
  101. pDouble_Indirect=new LPSTR* [in.nIndexNum];
  102. memset(pDouble_Indirect,0,in.nIndexNum*sizeof(LPSTR));
  103. nFree[0]=in.nIndexNum;
  104. }
  105. LPSTR MemTable::NEW()
  106. {
  107. LPSTR lpReturn;
  108. if(nFree[2]==0)//直接块用光了
  109. {
  110. if(nFree[1]==0)
  111. {
  112. if(nFree[0]==0)
  113. return NULL;//写日志:达到最大分配数量
  114. pIndirect=pDouble_Indirect[in.nIndexNum - nFree[0]]=new LPSTR [in.nIndexNum];
  115. memset(pIndirect,0,in.nIndexNum*sizeof(LPSTR));
  116. nFree[1]=in.nIndexNum-1;
  117. lpReturn=pIndirect[0]=new char[m_Vblkbytes];
  118. memset(lpReturn,0,m_Vblkbytes);
  119. nFree[2]=in.nUnitPerIndex-1;
  120. m_lpFirstFree = lpReturn + in.nUnitBytes;
  121. nFree[0]--;
  122. }
  123. else
  124. {
  125. lpReturn=pIndirect[in.nIndexNum - nFree[1]]=new char[m_Vblkbytes];
  126. memset(lpReturn,0,m_Vblkbytes);
  127. nFree[1]--;
  128. nFree[2]=in.nUnitPerIndex-1;
  129. m_lpFirstFree = lpReturn + in.nUnitBytes;
  130. }
  131. }
  132. else
  133. {
  134. lpReturn=m_lpFirstFree;
  135. nFree[2]--;
  136. m_lpFirstFree += in.nUnitBytes;
  137. }
  138. m_UnitTotalNum++;
  139. return lpReturn;
  140. }//by:www.datahf.net zhangyu(zhangyu.blog.51cto.com)
  141. UINT MemTable::NEW(UINT n)
  142. {
  143. UINT nReturn=m_UnitTotalNum;
  144. for(int i=0;i<n;i++)
  145. NEW();
  146. return nReturn;
  147. }
  148. LPSTR MemTable::NEW_CONTINUEOUS(UINT n)
  149. {
  150. LPSTR lpReturn;
  151. if(n>in.nUnitPerIndex)
  152. return NULL;
  153. if(nFree[2]>=n)
  154. {
  155. nFree[2]-=n;
  156. lpReturn=m_lpFirstFree;
  157. m_UnitTotalNum+=n;
  158. m_lpFirstFree += (n*in.nUnitBytes);
  159. }
  160. else
  161. {
  162. m_UnitTotalNum+=nFree[2];//剩余空间保留、忽略
  163. nFree[2]=0;
  164. lpReturn=NEW();
  165. nFree[2] -= (n-1);
  166. m_lpFirstFree += ((n-1)*in.nUnitBytes);
  167. m_UnitTotalNum += (n-1);
  168. }
  169. return lpReturn;
  170. }
  171. LPSTR MemTable::GET(UINT n)
  172. { //by:www.datahf.net zhangyu(zhangyu.blog.51cto.com)
  173. if(n>=m_UnitTotalNum)
  174. return NULL;//写日志:超过范围
  175. m_UnitID=n<< m_log2Lunits >>m_log2Lunits;
  176. m_index1ID=n >> m_log2Runits;
  177. m_index2ID=m_index1ID >> m_log2Rindexs;
  178. m_index1ID=m_index1ID <<m_log2Lindexs >>m_log2Lindexs;
  179. return (pDouble_Indirect[m_index2ID][m_index1ID] + (m_UnitID<<m_log2UnitBytes));
  180. }
  181. void MemTable::DEL()
  182. {
  183. }
本文转自 张宇 51CTO博客,原文链接:http://blog.51cto.com/zhangyu/680592,如需转载请自行联系原作者

c++内存优化:二级间接索引模式内存池相关推荐

  1. 操作系统-文件管理习题详细解析:设文件索引结点中又7个地址项,其中4个地址项是直接地址索引,2个地址项是一级间接地址索引,1个地址项是二级间接索引,每个地址项大小为4B,若磁盘索引块和磁盘数据块大小均

    题目:设文件索引结点中又7个地址项,其中4个地址项是直接地址索引,2个地址项是一级间接地址索引,1个地址项是二级间接索引,每个地址项大小为4B,若磁盘索引块和磁盘数据块大小均为256B,则可表示的单个 ...

  2. java内存优化详解_jvm堆内存优化详解

    在日常的运维工作中用到tomcat,都需要对tomcat中的jvm虚拟机进行优化,只有知道需要优化参数的具体用处,才能深刻体会优化jvm的意义所在. 在平常的工作中我们谈对jvm的优化,主要是针对ja ...

  3. android加载大量图片内存优化,Android图片加载内存优化

    利用BitmapFactory.Options实现图片内存优化 通过设置options.inPreferredConfig控制内存占用 首先准备了一张1280x800的blue_bg.png图片,我们 ...

  4. Android 内存优化实操,定位内存问题

    文章目录 一.内存泄漏定位 1.观察法: 2.使用内存分析工具 2-1.收集内存快照 2-2.hprof文件转换 2-3.Mat分析内存 二.内存抖动 三.优化内存空间 1.减少不必要的内存开销 2. ...

  5. 【Android 内存优化】垃圾回收算法 ( 内存优化总结 | 常见的内存泄漏场景 | GC 算法 | 标记清除算法 | 复制算法 | 标记压缩算法 )

    文章目录 一. 内存优化总结 二. 常见的内存泄漏场景 三. 内存回收算法 四. 标记-清除算法 ( mark-sweep ) 五. 复制算法 六. 标记-压缩算法 一. 内存优化总结 内存泄漏原理 ...

  6. 内存优化-使用tcmalloc分析解决内存泄漏和内存暴涨问题

    其实我一直很想写关于tcmalloc的内存泄漏检测的文章,只是一直记不起来该如何下笔,有时项目太忙,在整理这方便的思考过少,另外遇到的问题也不是很多,直到最近用tcmalloc帮A项目排查一些很棘手的 ...

  7. 安全管家安卓_内存优化管家v1.0下载-内存优化管家app最新版下载

    内存优化管家是一款安卓手机多功能清理工具,包含了文件垃圾.缓存垃圾.广告垃圾和内存垃圾等分类清理功能,使用方法简单,一键扫描手机,即可进行不同类型的垃圾划分, 用户可以根据需求进行筛选清理,除此之外, ...

  8. redis持久化、内存优化、过期、LRU内存

    为什么80%的码农都做不了架构师?>>>    1.过期(expire命令) 设置了失效时间的元素,对于DEL/SET/GETSET/*STORE这些会删除或者重新设置元素的命令,如 ...

  9. 行存储索引改换成列存储索引_索引策略–第2部分–内存优化表和列存储索引

    行存储索引改换成列存储索引 In the first part we started discussion about choosing the right table structure and d ...

最新文章

  1. webGL的一些咨询--web3D
  2. leveldb源码分析:数据查询
  3. 拒绝穿模!新方法让虚拟偶像自由互动无障碍“贴贴”,8000网友追着点赞
  4. [YTU]_2918( Shape系列-4)
  5. C和C++中的野指针问题
  6. python入门学习课程推荐
  7. Linux统计单个文件统计
  8. Ubuntu 17.10安装Qt 5.10环境与Qt Creator 4.5开发工具(转自linux公社)
  9. 实用卷积神经网络 运用python pdf_解析卷积神经网络—深度学习实践手册 中文pdf高清版...
  10. 美国弗吉尼亚大学计算机科学,弗吉尼亚大学计算机科学排名第31(2018年TFE美国排名)...
  11. 基于asp.net车辆管理调度系统的设计与实现
  12. ios APP加密探究几维安全iOS 代码混淆效果参考
  13. cc++语言参考手册_C ++值类别快速参考:第2部分
  14. SpringBoot整合MybatisPlus实战动态SQL,java定时器实现原理
  15. 微信小程序使用canvas画布
  16. 微信调试、手机QQ调试、Qzone之x5内核inspect调试解决方案
  17. 点餐系统架构模型_餐馆点餐系统课程设计
  18. px4+ros+gazebo+ORB_SLAM2室内视觉无人机导航
  19. Dev C++的安装以及基本使用方法
  20. 零束银河全栈技术解决方案之网络安全

热门文章

  1. 如何在VB6.0里动态使用具有事件的对象
  2. 人脸识别冤枉了98%的好人,伦敦警察局长:我很满意
  3. 你真的理解反向传播吗?面试必备
  4. 那么多GAN哪个好?谷歌大脑泼来冷水:都和原版差不多 | 论文
  5. oracle 12c dbca 无法发现 asm diskgroup
  6. 下个乳业蓝海风口 竟很可能是低温鲜奶?
  7. Swift实践:使用CoreData存储多种数据类的通讯录
  8. 洛谷——P1100 高低位交换
  9. 更改select里面的值
  10. C#面向对象名词比较(三)