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程序,因为有垃圾回收机制,应该没有内存泄露.其实如果我 们一个程序中,已经不再使用某个对象,但是因为仍然有引用指向它,垃圾回收器就无法回收它,当然该对象占用的内存就无法被使用,这就造 ...
随机推荐
- APC注入
0X01 注入原理 当线程被唤醒时APC中的注册函数会被执行的机制,并依此去调用我们的DLL加载代码,进而完成注入的目的 具体的流程: 1 当EXE里的某个线程执行到sleepEX(),或者waitF ...
- BZOJ 3410: [Usaco2009 Dec]Selfish Grazing 自私的食草者(贪心)
这= =,就是线段覆盖对了= =直接贪心就行了= = CODE: #include<cstdio>#include<iostream>#include<cstring&g ...
- Mysql删除表格之后,进行恢复
一:存在在PHPmyAdmin下找到表格导出然后再导入 二:当没有备份时,使用binlog功能进行恢复 先进入到/etc/my.cnf文件中. 在文件中添加一句:log-bin=mysql-bin 然 ...
- 规范 : jobbox 中英文
中英文是为了candidate 可以看到不同的post job 语言. e.g. 如果是contact person 的“designation” ,这个不会显示在post job 里,目的只是给em ...
- nginx配置参数详解
配置参数详解 user nginx nginx ; Nginx用户及组:用户 组.window下不指定 worker_processes 8; 工作进程:数目.根据硬件调整,通常等于CPU数量或者2倍 ...
- 《Django By Example》第七章 中文 翻译 (个人学习,渣翻)
书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者@ucag注:咳咳,第七章终于来了.其 ...
- 对java数组的一些理解
刚开始学习Java的时候一直搞不清除获取数组的长度是用length()还是length,现在不妨来深入了解一下数组的真实面目. 我们不妨来看一下数组的源码,诶,数组的类名叫什么?我们声明一个int数组 ...
- 从USB驱动器运行Windows 10
我相信很多人和我一样.梦想着有个随身携带的U盘版操作系统.无论走到哪里,只要有电脑都可以随时运行自己配置好的操作系统.本篇博文就会一步步的教你如何从USB驱动器加载和运行Windows 10. 让我想 ...
- Azure Messaging-ServiceBus Messaging消息队列技术系列4-复杂对象消息是否需要支持序列化和消息持久化
在上一篇中,我们介绍了消息的顺序收发保证: Azure Messaging-ServiceBus Messaging消息队列技术系列3-消息顺序保证 在本文中我们主要介绍下复杂对象消息是否需要支持序列 ...
- C#:判断100--999之前的水仙花数
//判断100--999之前的水仙花数.水仙花数举例:153=13+53+33. using System;public class Program { public static void ...