再说内存池
来源:互联网 发布:windows live影音软件 编辑:程序博客网 时间:2024/05/24 06:23
根据<<提高C++性能的编程技术>>文章描述,对内存池各种情况进行了改写和对比
一下在vs2013下实践得到的数据
需要分配的内存
class CRational
{
public:
CRational(int a = 0, int b = 1)
: n_(a),
d_(b)
{
}
private:
int n_; // 分子
int d_; // 分母
};
1、普通的内存分配
void CTest6_2::test1()
{
CRational* pRation[1000];
long l1 = time(NULL);
for (int j = 0; j < 500; ++j)
{
for (int i = 0; i < 1000; ++i)
{
pRation[i] = new CRational(i);
}
for (int i = 0; i < 1000; ++i)
{
delete pRation[i];
}
}
long l2 = time(NULL);
cout << "test1: " << l2 - l1 << endl;
}
得到的时间是7S
2.单线程下的内存分配
CRationalEx* pRation[1000];
long l1 = time(NULL);
CRationalEx::newMemPool();
for (int j = 0; j < 500; ++j)
{
for (int i = 0; i < 1000; ++i)
{
pRation[i] = new CRationalEx(i);
}
for (int i = 0; i < 1000; ++i)
{
delete pRation[i];
}
}
CRationalEx::deleteMemPool();
long l2 = time(NULL);
cout << "test2: " << l2 - l1 << endl;
时间可以控制在1s内了
内存池的简单实现
class NextOnFreeList
{
public:
NextOnFreeList()
: p_next_(0)
{
}
NextOnFreeList* p_next_; // 内存链路
};
// 单线程环境下的内存分配
class CRationalEx
{
public:
inline void* operator new(size_t size);
inline void operator delete(void* doomed, size_t size);
static void newMemPool(){ expandTheFreeList(); }
static void deleteMemPool();
CRationalEx(int a = 0, int b = 1)
: n_(a),
d_(b)
{
}
private:
int n_; // 分子
int d_; // 分母
static NextOnFreeList* p_free_list_;
static void expandTheFreeList();
};
// 分配内存的算法
void CRationalEx::expandTheFreeList()
{
size_t size = (sizeof(CRationalEx) > sizeof(NextOnFreeList*) ? sizeof(CRationalEx) : sizeof(NextOnFreeList));
void* pchar = new char[size]; // 分配一个CRationalEx大小的空间
NextOnFreeList* prunner = static_cast<NextOnFreeList*>(pchar);
p_free_list_ = prunner;
for (int i = 0; i < EXPANSION_SIZE; ++i)
{
pchar = new char[size];
prunner->p_next_ = static_cast<NextOnFreeList*>(pchar);// next连接
prunner = prunner->p_next_;
}
prunner->p_next_ = 0;
}
// 函数内联,保证了更快的速度,需要分配CRationalEx时,直接从内存池取用
inline void* CRationalEx::operator new(size_t size)
{
if (!p_free_list_)
{
expandTheFreeList(); // 空间不够了,再分配32个CRationalEx
}
NextOnFreeList* phead = p_free_list_;
p_free_list_ = phead->p_next_;
return phead; // 返回首地址的空间出去,然后现有内存池指向下一个
}
inline void CRationalEx::operator delete(void* doomed, size_t size)
{
NextOnFreeList* head = static_cast<NextOnFreeList*>(doomed); // 释放空间,即调用CRationalEx时,只是把内存池再还给NexOnFreeList
head->p_next_ = p_free_list_;// 把地址拿过来,然后里面的next赋值成当前的head,这样把归还的地址放在最前面了,下次new取用也是从最前面取用
p_free_list_ = head;
}
// 真正的释放内存池的内存
void CRationalEx::deleteMemPool()
{
NextOnFreeList* pnext_ptr;
for (pnext_ptr = p_free_list_; pnext_ptr != NULL; pnext_ptr = p_free_list_)
{
p_free_list_ = p_free_list_->p_next_;
delete[] pnext_ptr;
}
}
- 再说内存池
- 再说 c++11 内存模型
- 再说 c++11 内存模型
- 再说Runnable、Callable、Future、线程池
- Dubbo源代码分析八:再说Provider线程池被EXHAUSTED
- 再说测试
- 再说分页
- 再说痰
- 再说MVC
- 开通再说
- 再说线程
- 再说Ucweb
- 再说springsecurity
- 再说RCA
- 再说python
- 再说指针
- 刷点分再说
- 再说墨水
- 利用word2vec对关键词进行聚类
- cf#3A Shortest path of the kinghttp://codeforces.com/contest/3/problem/A
- 使用V7包的一些问题解决方法
- 网狐棋牌(八) 异步引擎 和 网狐棋牌(九) 服务引擎概览
- 栈-----顺序储存结
- 再说内存池
- 网狐棋牌(十) 成也萧何败也肖何? IUnknowEx
- HashTable、HashSet和Dictionary的区别
- ios通过app读取通讯录信息
- 测试博客
- JDK1.7(jdk7.0)新特性
- 利用openresty-lua生态修改upstream后端服务
- 【转】MongoDB的java版本驱动
- 菜鸟学习Spring——SpringMVC注解版前台向后台传值的两种方式GOOD