//
/*
1.为什么需要cache,有那些好处?
从下面几点考虑
后台程序会创建大量的对象,也就是动态分配内存,通常的做法是new XXX。然后在
不用的时候在delete XXX。这样new和delete会消耗一定cpu,最重要的是在长期new/delete
后会有内存碎片,而且忘记delete XXX,那就会有致命的内存泄漏这种bug将是难以调试和查找的。
内存使用策略优先级从下到下
尽量避免动态内存分配,做到一次性内存分配,运行期间不使用new/delete)
尽量少用动态分配内存
优化调锁的内存池
使用内存分配池
实时动态分配内存,直接使用new/delete
2.那些数据需要cache,如何评估需要的内存空间
评估需要的内存空间,就得先确定那些是要cache的,一般像Role,Monster,Item都可以Cache,在就是确定数量
比如一个LogicServer最大服务人数为5000,那么Role的内存所需内存大小为sizeof(Role)*5000,其他都可以这么来估算
3.确定cache策略如果保证高效找出(cache命中要高),如果实现cache和复用Cache组件
实现方法有很多,下面是一种实现,不过可以有几个地方可以改进
1.是否可以让cache的空间来自共享内存?
2.是否可以不用std的容器自己实现vector和hash来支持cache内部结构?
3.如果使用共享内存,那么在服务重启的时候如何重用上次的共享内存?
*/
template<class T>
struct MemoryBlock
{
int key;
int next;
T data;
};
template<class T,int size>
class MemoryCache
{
private:
void InitMemory()
{
for (int i=0;i<size;++i)
{
MemoryBlock<T>* pblock = NULL;
pblock = &(m_Memblocks.at(i));
pblock->key = 0;
pblock->next = i + 1;
}
}
MemoryBlock<T>* GetBlock(int index)
{
if (index < 0 || index >= size)
{
return NULL;
}
MemoryBlock<T>* pblock = NULL;
pblock = &(m_Memblocks.at(index));
return pblock;
}
public:
MemoryCache()
{
//分配空间
m_Memblocks.resize(size);
m_Count = 0;
m_FreeHead = 0;
m_Size = size;
InitMemory();
}
T* GetDataByKey(int key)
{
if (0 == key)
{
return NULL;
}
std::map<int,int>::iterator iter = m_HashKey.find(key);
if (iter == m_HashKey.end())
{
return NULL;
}
int index = iter->second;
MemoryBlock<T>* pblock = GetBlock(index);
return &(pblock->data);
}
T* AllcoMemory(int key)
{
if (0 == key)
{
return NULL;
}
T* pdata = GetDataByKey(key);
if (pdata)
{
return pdata; //hit cache
}
//not find alloc memory
int curindex = m_FreeHead;
MemoryBlock<T>* pBlock = GetBlock(curindex);
if (NULL == pBlock)
{
return NULL;
}
pBlock->key = key;
m_FreeHead = pBlock->next;
pBlock->next = 0;
m_HashKey.insert(std::make_pair(key,curindex));
return &(pBlock->data);
}
bool Remove(int key)
{
std::map<int,int>::iterator iter = m_HashKey.find(key);
if (iter == m_HashKey.end())
{
//not find
return false;
}
int index = iter->second;
MemoryBlock<T>* pblock = GetBlock(index);
if (pblock->key == key)
{
int PreIndex = index;
pblock->next = m_FreeHead;
pblock->key = 0;
m_FreeHead = PreIndex;
m_HashKey.erase(iter);
}
return true;
}
int Size() { return m_Count; }
int Capacity() { return m_Size;}
private:
//存储实际数据
std::vector<MemoryBlock<T> > m_Memblocks;
//存储<key,index>
std::map<int,int> m_HashKey;
//当前实际元素size
unsigned int m_Count;
int m_Size;
//总是指向预分配的index
unsigned int m_FreeHead;
};
//
struct Role
{
int key;
int x;
int y;
int hp;
};
typedef MemoryCache<Role,6000> RoleCache;
//typedef MemoryCache<Monster,10000> MonsterCache;
int main(int argc, char** argv)
{
//定义一个Role cache
RoleCache rolecacle;
//申请空间
Role* pRole1 = rolecacle.AllcoMemory(1000);
//初始化Role
pRole1->key = 1000;
pRole1->x = 10;
pRole1->y = 10;
pRole1->hp = 500;
Role* pRole2 = rolecacle.AllcoMemory(1005);
pRole2->key = 1005;
pRole2->x = 50;
pRole2->y = 50;
pRole2->hp = 200;
//销毁对象
/*
1.为什么需要cache,有那些好处?
从下面几点考虑
后台程序会创建大量的对象,也就是动态分配内存,通常的做法是new XXX。然后在
不用的时候在delete XXX。这样new和delete会消耗一定cpu,最重要的是在长期new/delete
后会有内存碎片,而且忘记delete XXX,那就会有致命的内存泄漏这种bug将是难以调试和查找的。
内存使用策略优先级从下到下
尽量避免动态内存分配,做到一次性内存分配,运行期间不使用new/delete)
尽量少用动态分配内存
优化调锁的内存池
使用内存分配池
实时动态分配内存,直接使用new/delete
2.那些数据需要cache,如何评估需要的内存空间
评估需要的内存空间,就得先确定那些是要cache的,一般像Role,Monster,Item都可以Cache,在就是确定数量
比如一个LogicServer最大服务人数为5000,那么Role的内存所需内存大小为sizeof(Role)*5000,其他都可以这么来估算
3.确定cache策略如果保证高效找出(cache命中要高),如果实现cache和复用Cache组件
实现方法有很多,下面是一种实现,不过可以有几个地方可以改进
1.是否可以让cache的空间来自共享内存?
2.是否可以不用std的容器自己实现vector和hash来支持cache内部结构?
3.如果使用共享内存,那么在服务重启的时候如何重用上次的共享内存?
*/
template<class T>
struct MemoryBlock
{
int key;
int next;
T data;
};
template<class T,int size>
class MemoryCache
{
private:
void InitMemory()
{
for (int i=0;i<size;++i)
{
MemoryBlock<T>* pblock = NULL;
pblock = &(m_Memblocks.at(i));
pblock->key = 0;
pblock->next = i + 1;
}
}
MemoryBlock<T>* GetBlock(int index)
{
if (index < 0 || index >= size)
{
return NULL;
}
MemoryBlock<T>* pblock = NULL;
pblock = &(m_Memblocks.at(index));
return pblock;
}
public:
MemoryCache()
{
//分配空间
m_Memblocks.resize(size);
m_Count = 0;
m_FreeHead = 0;
m_Size = size;
InitMemory();
}
T* GetDataByKey(int key)
{
if (0 == key)
{
return NULL;
}
std::map<int,int>::iterator iter = m_HashKey.find(key);
if (iter == m_HashKey.end())
{
return NULL;
}
int index = iter->second;
MemoryBlock<T>* pblock = GetBlock(index);
return &(pblock->data);
}
T* AllcoMemory(int key)
{
if (0 == key)
{
return NULL;
}
T* pdata = GetDataByKey(key);
if (pdata)
{
return pdata; //hit cache
}
//not find alloc memory
int curindex = m_FreeHead;
MemoryBlock<T>* pBlock = GetBlock(curindex);
if (NULL == pBlock)
{
return NULL;
}
pBlock->key = key;
m_FreeHead = pBlock->next;
pBlock->next = 0;
m_HashKey.insert(std::make_pair(key,curindex));
return &(pBlock->data);
}
bool Remove(int key)
{
std::map<int,int>::iterator iter = m_HashKey.find(key);
if (iter == m_HashKey.end())
{
//not find
return false;
}
int index = iter->second;
MemoryBlock<T>* pblock = GetBlock(index);
if (pblock->key == key)
{
int PreIndex = index;
pblock->next = m_FreeHead;
pblock->key = 0;
m_FreeHead = PreIndex;
m_HashKey.erase(iter);
}
return true;
}
int Size() { return m_Count; }
int Capacity() { return m_Size;}
private:
//存储实际数据
std::vector<MemoryBlock<T> > m_Memblocks;
//存储<key,index>
std::map<int,int> m_HashKey;
//当前实际元素size
unsigned int m_Count;
int m_Size;
//总是指向预分配的index
unsigned int m_FreeHead;
};
//
struct Role
{
int key;
int x;
int y;
int hp;
};
typedef MemoryCache<Role,6000> RoleCache;
//typedef MemoryCache<Monster,10000> MonsterCache;
int main(int argc, char** argv)
{
//定义一个Role cache
RoleCache rolecacle;
//申请空间
Role* pRole1 = rolecacle.AllcoMemory(1000);
//初始化Role
pRole1->key = 1000;
pRole1->x = 10;
pRole1->y = 10;
pRole1->hp = 500;
Role* pRole2 = rolecacle.AllcoMemory(1005);
pRole2->key = 1005;
pRole2->x = 50;
pRole2->y = 50;
pRole2->hp = 200;
//销毁对象
rolecacle.Remove(pRole1->key);
}