c++内存优化:二级间接索引模式内存池
/*********************************************************
在一些不确定内存总占用量的情形下,频繁的使用new申请内存,再通过链表
进行索引似乎是很常规的做法。自然,也很难做到随机定位。
下面的内存池类是用二层索引表来对内存进行大块划分,任何一个块均只需索
引3次即可定位。
索引数量,每索引块的分配单元数量,以及分配单元的字节长度均需为2的整数
次幂(为了运算时的效率)
//by:www.frombyte.com zhangyu(zhangyu.blog.51cto.com)
*********************************************************/
class MemTable
{
public:
MemTable(void);
public:
~MemTable(void);
public:
void CREATE(MemTableIn *in_m);
void DEL();
LPSTR NEW();//分配一个unit
LPSTR NEW_CONTINUEOUS(UINT n);//用于连续分配若干个unit
UINT NEW(UINT n); //用于可碎片方式分配若干个unit
LPSTR GET(UINT n);//用来获得第n个分配的指针地址
int get_totle_unitnum();
public:
MemTableIn in;
LPSTR **pDouble_Indirect;
LPSTR lpBitmap;
LPSTR *pIndirect; LPSTR m_lpFirstFree;
int nFree[];//0表示二级索引的自由,1表示1级索引的自由,2表示块自由索引号
INT32 m_EndBlkUseredUnits;
int m_Vblkbytes;
UINT m_UnitTotalNum;
UINT m_log2Rindexs,m_log2Runits,m_log2Rbitmap,m_log2Lindexs,m_log2Lunits,m_log2Lbitmap;
UINT m_log2UnitBytes;
UINT m_index2ID,m_index1ID,m_UnitID;
};
在一些不确定内存总占用量的情形下,频繁的使用new申请内存,再通过链表
进行索引似乎是很常规的做法。自然,也很难做到随机定位。
下面的内存池类是用二层索引表来对内存进行大块划分,任何一个块均只需索
引3次即可定位。
索引数量,每索引块的分配单元数量,以及分配单元的字节长度均需为2的整数
次幂(为了运算时的效率)
CPP内容如下:
/**
* ffs - Find the first set bit in an int
* @x:
*
* Description...用来统计一个整型数据的最高为1的位,后面有多少位。
*换个说法:从最高位开始找1,找到1后,看这个二进制数据1000....000是2的几次方
*
* Returns:
*/
int ffs(int x)
{
int r = ; if (!x)
return ;
if (!(x & 0xffff)) {
x >>= ;
r += ;
}
if (!(x & 0xff)) {
x >>= ;
r += ;
}
if (!(x & 0xf)) {
x >>= ;
r += ;
}
if (!(x & )) {
x >>= ;
r += ;
}
if (!(x & )) {
x >>= ;
r += ;
}
return r;
}
LPSTR MemTree::GET(MemTreeHead *pHead,UINT n)
{
int t;
LPSTR lpt;
int i,ii;
//判断是否直接存储
if(n<m.rootDirectUnitNum)
return pHead->lpRootUnit + n*m.Vsizeof;
else
t=n-m.rootDirectUnitNum; for(i=;i<DEEP;i++)
{
if(t<TBT[i][])
break;
t-=TBT[i][];
}
//i便是深度,t是深度内的n
lpt=pHead->pROOT_INDEX[i-];
int D;
for(ii=;ii<i;ii++)
{
D=t /TBT[i][ii];
t=t % TBT[i][ii];
lpt=*(LPSTR*)(lpt+sizeof(LPSTR)*D);
}
return (lpt + t*m.Vsizeof); } MemTable::MemTable(void)
{
} MemTable::~MemTable(void)
{
//释放所有空间
for(int i=;i<in.nIndexNum;i++)
{
LPSTR *pp=pDouble_Indirect[i];
if(pp==NULL)
break;
for(int ii=;ii<in.nIndexNum;ii++)
{
LPSTR p=pp[ii];
if(p==NULL)
break;
else
delete [] p;
}
delete [] pp;
}
delete [] pDouble_Indirect;
}
void MemTable::CREATE(MemTableIn *in_m)
{
//1、初始化一些参考块
memset(&in,,sizeof(in));
in=*in_m;
m_UnitTotalNum=;
nFree[]=nFree[]=nFree[]=; m_Vblkbytes= in.nUnitBytes *in.nUnitPerIndex;
m_log2Runits=ffs(in.nUnitPerIndex)-;
m_log2Rindexs=ffs(in.nIndexNum)-;
m_log2UnitBytes=ffs(in.nUnitBytes)-; m_log2Lindexs=sizeof(UINT)*-m_log2Rindexs;
m_log2Lunits=sizeof(UINT)*-m_log2Runits; //2、初始化二级索引表
pDouble_Indirect=new LPSTR* [in.nIndexNum];
memset(pDouble_Indirect,,in.nIndexNum*sizeof(LPSTR));
nFree[]=in.nIndexNum;
}
LPSTR MemTable::NEW()
{
LPSTR lpReturn;
if(nFree[]==)//直接块用光了
{
if(nFree[]==)
{
if(nFree[]==)
return NULL;//写日志:达到最大分配数量 pIndirect=pDouble_Indirect[in.nIndexNum - nFree[]]=new LPSTR [in.nIndexNum];
memset(pIndirect,,in.nIndexNum*sizeof(LPSTR));
nFree[]=in.nIndexNum-; lpReturn=pIndirect[]=new char[m_Vblkbytes];
memset(lpReturn,,m_Vblkbytes);
nFree[]=in.nUnitPerIndex-;
m_lpFirstFree = lpReturn + in.nUnitBytes;
nFree[]--; }
else
{
lpReturn=pIndirect[in.nIndexNum - nFree[]]=new char[m_Vblkbytes];
memset(lpReturn,,m_Vblkbytes);
nFree[]--;
nFree[]=in.nUnitPerIndex-;
m_lpFirstFree = lpReturn + in.nUnitBytes;
}
}
else
{
lpReturn=m_lpFirstFree;
nFree[]--;
m_lpFirstFree += in.nUnitBytes;
}
m_UnitTotalNum++;
return lpReturn; }//by:www.frombyte.com zhangyu(zhangyu.blog.51cto.com)
UINT MemTable::NEW(UINT n)
{
UINT nReturn=m_UnitTotalNum;
for(int i=;i<n;i++)
NEW();
return nReturn; }
LPSTR MemTable::NEW_CONTINUEOUS(UINT n)
{
LPSTR lpReturn;
if(n>in.nUnitPerIndex)
return NULL; if(nFree[]>=n)
{
nFree[]-=n;
lpReturn=m_lpFirstFree;
m_UnitTotalNum+=n;
m_lpFirstFree += (n*in.nUnitBytes);
}
else
{
m_UnitTotalNum+=nFree[];//剩余空间保留、忽略
nFree[]=;
lpReturn=NEW();
nFree[] -= (n-);
m_lpFirstFree += ((n-)*in.nUnitBytes);
m_UnitTotalNum += (n-);
}
return lpReturn;
}
LPSTR MemTable::GET(UINT n)
{ //by:www.frombyte.com zhangyu(zhangyu.blog.51cto.com)
if(n>=m_UnitTotalNum)
return NULL;//写日志:超过范围
m_UnitID=n<< m_log2Lunits >>m_log2Lunits;
m_index1ID=n >> m_log2Runits;
m_index2ID=m_index1ID >> m_log2Rindexs;
m_index1ID=m_index1ID <<m_log2Lindexs >>m_log2Lindexs; return (pDouble_Indirect[m_index2ID][m_index1ID] + (m_UnitID<<m_log2UnitBytes)); }
void MemTable::DEL()
{ }
c++内存优化:二级间接索引模式内存池的更多相关文章
- SQL Server 内存优化表的索引设计
测试的版本:SQL Server 2017 内存优化表上可以创建哈希索引(Hash Index)和内存优化非聚集(NONCLUSTERED)索引,这两种类型的索引也是内存优化的,称作内存优化索引,和基 ...
- linux内存优化之手工释放linux内存
先介绍下free命令 Linux free命令用于显示内存状态. free指令会显示内存的使用情况,包括实体内存,虚拟的交换文件内存,共享内存区段,以及系统核心使用的缓冲区等. 语法: free [- ...
- 试试SQLSERVER2014的内存优化表
试试SQLSERVER2014的内存优化表 SQL Server 2014中的内存引擎(代号为Hekaton)将OLTP提升到了新的高度. 现在,存储引擎已整合进当前的数据库管理系统,而使用先进内存技 ...
- SQLServer2014内存优化表评测
SQLServer2014内存优化表评测 分类: SQL内存表2014-06-20 11:49 1619人阅读 评论(11) 收藏 举报 目录(?)[-] SQLServer2014的使用基本要求 内 ...
- SQLSERVER2014的内存优化表
SQL Server 2014中的内存引擎(代号为Hekaton)将OLTP提升到了新的高度. 现在,存储引擎已整合进当前的数据库管理系统,而使用先进内存技术来支持大规模OLTP工作负载. 就算如此, ...
- 试试SQLServer 2014的内存优化表
SQL Server2014存储引擎:行存储引擎,列存储引擎,内存引擎 SQL Server 2014中的内存引擎(代号为Hekaton)将OLTP提升到了新的高度. 现在,存储引擎已整合进当前的数据 ...
- 试试SQLServer 2014的内存优化表(转载)
SQL Server2014存储引擎:行存储引擎,列存储引擎,内存引擎 SQL Server 2014中的内存引擎(代号为Hekaton)将OLTP提升到了新的高度. 现在,存储引擎已整合进当前的数据 ...
- Android 性能优化 - 详解内存优化的来龙去脉
前言 APP内存的使用,是评价一款应用性能高低的一个重要指标.虽然现在智能手机的内存越来越大,但是一个好的应用应该将效率发挥到极致,精益求精. 这一篇中我们将着重介绍Android的内存优化.本文的篇 ...
- android 开发如何做内存优化
不少人认为JAVA程序,因为有垃圾回收机制,应该没有内存泄露.其实如果我 们一个程序中,已经不再使用某个对象,但是因为仍然有引用指向它,垃圾回收器就无法回收它,当然该对象占用的内存就无法被使用,这就造 ...
随机推荐
- Python thread local
由于GIL的原因,笔者在日常开发中几乎没有用到python的多线程.如果需要并发,一般使用多进程,对于IO Bound这种情况,使用协程也是不错的注意.但是在python很多的网络库中,都支持多线程, ...
- JavaScript中国象棋程序(8) - 进一步优化
在这最后一节,我们的主要工作是使用开局库.对根节点的搜索分离出来.以及引入PVS(Principal Variation Search,)主要变例搜索. 8.1.开局库 这一节我们引入book.js文 ...
- 架设WIN32汇编程序的开发环境
笔者在学习Windows下的图形界面应用程序(GUI,Graphical User Interface)的时候碰到的第一个麻烦就是架设WIN32汇编程序的开发环境,在这里笔者愿意和大家分享这段经历. ...
- Android Weekly Notes Issue #245
Android Weekly Issue #245 February 19th, 2017 Android Weekly Issue #245 本期内容: 写好单元测试的几条原则; 如何mock Ko ...
- Finding distance between two curves
http://answers.opencv.org/question/129819/finding-distance-between-two-curves/ 问题: Hello, Im trying ...
- 一次MySQL死锁问题解决
一次MySQL死锁问题解决 一.环境 CentOS, MySQL 5.6.21-70, JPA 问题场景:系统有定时批量更新数据状态操作,每次更新上千条记录,表中总记录数约为500W左右. 二.错误日 ...
- 规范 : loading display & ui-view loading
angular 没有compile 完成的接口,最像的接口是$viewContentLoaded(router ui),但是一开始会开始跑,因为有ui-view 暂时解决方法是在body的loadin ...
- FineUIMvc随笔(4)自定义回发参数与自定义回发
声明:FineUIMvc(基础版)是免费软件,本系列文章适用于基础版. 不能忘却的回发 在上一篇文章中,我们对FineUIMvc中的回发进行了详细描述,目的是为了告诉大家: 1. FineUIMvc中 ...
- 成为一名合格的ERP实施顾问应该具备哪些修为
要想成为一个合格ERP实施顾问,究竟需要点什么素质.请注意,这里的素质与技能是两码事,素质特别强调的是某种修养,技能可以速成,修养必须积累沉淀. 快速切入客户业务的能力 作为一个合格的ERP实施人员, ...
- Yii地址美化(nginx环境)
通过urlmanager实现yii地址美化,需配合服务器中的rewrite配置 1.在'components'中加入 'urlManager'=>array( 'ur ...