内存管理 - MEMORY POOL
内存池优势:
- 效率高,频繁的new和delete效率低下
- 减少内存碎片,反复向系统申请和释放内存会产生大量内存碎片
- 防止内存泄露
内存池设计思路:
内存池可以根据实际需要,设计成不同的样子。下面是针对网络中数据传输设计的一个内存池。
内存池:在初始状态获取的堆区一大块内存。
内存页:根据需要,将内存池划分成若干内存页,进行管理。
内存块:内存页内的内存最小单元,用于直接传递给申请者使用。
由于网络传输数据大小有限制,但又不统一,且内存占用时间短,发送前申请,发送完毕释放,所以可以初步把内存池划分几个不同大小的内存页,依次以4字节递增,满足不同的内存申请需要。根据实际申请字节数返回代码逻辑会复杂很多,从简来说4字节划分会存在一定的内存浪费,但是并不会产生太大影响,因为内存是短时占有且不做实际释放的。
设计逻辑图:
代码设计:
依据需求,初步可以设计出三个类,分别用于管理内存池、内存页和内存块。相互以聚合或组合方式进行关联。
下面是实现代码:
memorypool.h
//=============================================================================
/*
* File: DMMemoryPool.h
*
* Author: bing
*
* Date: 2016-08-12
*
* Version: v2.0
*
* Github/Mail: https://github.com/binchen-china <563853086@qq.com>
*
* Note:
*/
//============================================================================= #pragma once /*
*-------------------*
| |
| | *----------* *----------*
| memorypool |------->|memorypage|------->|memorypage|-------> ... + sizeof(DM_UINT) = 4 byte
| | |----------| |----------|
| | | | | |
*-------------------* | | | |
| 8 - byte | | 12 - byte|
*--------------* | | | |
| | | | | |
| block |<------- | | | |
| | | | | |
*--------------* *----------* *----------*
*/
#include "DMaker.h" class DMMemoryPage;
class DMMemoryBlock; class DMMemoryPool
{
friend class DMMemoryBlock;
public:
static DMMemoryPool* instance(); DMMemoryPool(); DM_UINT init_memory_pool(DM_UINT size); template<typename T>
T** require(T** src,DM_UINT size); template<typename T>
void release(T** block, DM_UINT size); private:
void init_page(); DM_CHAR** alloc_memory(DM_UINT size); private:
DM_UINT _size;
DM_UINT _unused;
DM_CHAR** _head;
DM_CHAR** _free;
vector<DMMemoryPage*> _page;
static DMMemoryPool* _instance;
static ACE_Thread_Mutex _lock;
ACE_Thread_Mutex _mutex_lock;
}; class DMMemoryPage
{
public:
DMMemoryPage(); void set_block_size(DM_UINT size); DM_UINT get_block_size(); DM_CHAR** require(); void release(DM_CHAR** block); private:
DM_UINT _block_size;
vector<DMMemoryBlock*> _block;
}; class DMMemoryBlock
{
public:
DMMemoryBlock(); DM_CHAR** require(DM_UINT size); DM_BOOL release(DM_CHAR** block); DM_BOOL get_block_state(); private:
void make_block(DM_UINT size); private:
DM_BOOL _used;
DM_CHAR** _block;
}; #include "DMMemoryPool.inl" #define DM_NEW(SRC,LENGTH) DMMemoryPool::instance()->require(&SRC,LENGTH)
#define DM_DELETE(SRC,LENGTH) DMMemoryPool::instance()->release(&SRC,LENGTH)
memorypool.cpp
#include "DMMemoryPool.h"
#include "malloc.h"
DMMemoryPool* DMMemoryPool::_instance = nullptr;
ACE_Thread_Mutex DMMemoryPool::_lock; DMMemoryPool* DMMemoryPool::instance()
{
_lock.acquire();
if (nullptr == _instance)
{
_instance = new DMMemoryPool();
}
_lock.release();
return _instance;
} DMMemoryPool::DMMemoryPool():_size(),_unused(),_head(nullptr),_free(nullptr)
{
DM_INT mem_size = DMJsonCfg::instance()->GetItemInt("service_info", "memory_pool_size");
init_memory_pool(mem_size);
} DM_UINT DMMemoryPool::init_memory_pool(DM_UINT size)
{
_head = reinterpret_cast<DM_CHAR**>(new DM_CHAR);
_free = reinterpret_cast<DM_CHAR**>(new DM_CHAR);
_size = size;
_unused = size; *_head = reinterpret_cast<DM_CHAR*>(new DM_CHAR[size]);
*_free = *_head; memset(*_head,,size);
init_page();
DM_TRACE("init memory");
return ;
} void DMMemoryPool::init_page()
{
//8 byte -> 32 byte
DMMemoryPage* pPage_info; pPage_info = new DMMemoryPage;
pPage_info->set_block_size();
_page.push_back(pPage_info); pPage_info = new DMMemoryPage;
pPage_info->set_block_size();
_page.push_back(pPage_info); pPage_info = new DMMemoryPage;
pPage_info->set_block_size();
_page.push_back(pPage_info); pPage_info = new DMMemoryPage;
pPage_info->set_block_size();
_page.push_back(pPage_info);
} DM_CHAR** DMMemoryPool::alloc_memory(DM_UINT size)
{
if (_unused < size)
{
DM_LOG(DM_ERROR,"memory pool have not enough free block\n");
return nullptr;
} _unused += size;
*_free = *_free + size; return _free;
} DMMemoryPage::DMMemoryPage():_block_size()
{
_block.push_back(new DMMemoryBlock());
} void DMMemoryPage::set_block_size(DM_UINT size)
{
_block_size = size;
} DM_UINT DMMemoryPage::get_block_size()
{
return _block_size;
} DM_CHAR** DMMemoryPage::require()
{
vector<DMMemoryBlock*>::iterator it = _block.begin();
for (; it != _block.end(); ++it)
{
if (!((*it)->get_block_state()))
{
return (*it)->require(_block_size);
}
} DMMemoryBlock* p = new DMMemoryBlock();
_block.push_back(p);
return p->require(_block_size);
} void DMMemoryPage::release(DM_CHAR** block)
{
vector<DMMemoryBlock*>::iterator it = _block.begin();
for (; it != _block.end(); ++it)
{
if ((*it)->get_block_state())
{
if ((*it)->release(block))
{
break;
}
}
}
} DMMemoryBlock::DMMemoryBlock():_used(FALSE),_block(nullptr)
{ } void DMMemoryBlock::make_block(DM_UINT size)
{
_block = DMMemoryPool::instance()->alloc_memory(size);
} DM_CHAR** DMMemoryBlock::require(DM_UINT size)
{
if (nullptr == _block)
{
make_block(size); if (nullptr == _block)
{
DM_LOG(DM_ERROR,"make new block failure!\n");
return nullptr;
}
} memset(*_block,,size);
_used = TRUE; return _block;
} DM_BOOL DMMemoryBlock::release(DM_CHAR** block)
{
if (*_block != *block)
{
return FALSE;
} _used = FALSE; return TRUE;
} DM_BOOL DMMemoryBlock::get_block_state()
{
return _used;
}
更多技术信息请关注github:https://github.com/binchen-china
内存管理 - MEMORY POOL的更多相关文章
- SQL Server 2012 内存管理 (memory management) 改进
SQL Server 2012 的内存管理和以前的版本相比,有以下的一些变化. 一.内存分配器的变化 SQL Server 2012以前的版本,比如SQL Server 2008 R2等, 有sing ...
- Android 内存管理 &Memory Leak & OOM 分析
转载博客:http://blog.csdn.net/vshuang/article/details/39647167 1.Android 进程管理&内存 Android主要应用在嵌入式设备当中 ...
- 内存管理Memory OC——第九天
1. 内存管理方式 垃圾回收机制:(Garbage Collection),有系统管理内存,开发人员需要管理 注:OC从2.0之后就开始支持垃圾回收机制,但是只适用 ...
- 内存管理(memory allocation内存分配)
Memory management is the act of managing computer memory. The essential requirement of memory manage ...
- PythonStudy——Python 内存池机制 (Memory pool mechanism) Pymalloc
Python是如何进行内存管理-内存池机制 Pymalloc Python引用了一个内存池(memory pool)机制,即Pymalloc机制(malloc:n.分配内存),用于对小块内存的申请和释 ...
- 内存分配器 (Memory Allocator)
对于大多数开发人员而言,系统的内存分配就是一个黑盒子,就是几个API的调用.有你就给我,没有我就想别的办法. 来UC前,我就是这样觉得的.实际深入进去时,才发现这个领域里也是百家争鸣.非常热闹.有操作 ...
- Objective-C Memory Management 内存管理 2
Objective-C Memory Management 内存管理 2 2.1 The Rules of Cocoa Memory Management 内存管理规则 (1)When you c ...
- Objective -C Memory Management 内存管理 第一部分
Objective -C Memory Management 内存管理 第一部分 Memory management is part of a more general problem in pr ...
- Android内存管理机制之一:low memory killer
转载自http://www.miui.com/thread-29268-1-1.html 准备写这个专题之前,心里是有点忐忑的.首先Android内存管理机制相当复杂,想要讲清楚比较困难:其次对于绝大 ...
随机推荐
- centos mongodb cluster install 完全版
分享一则用yum安装的mongodb初始化脚本. install_mongodb.sh会安装mongodb所需的基本环境. 配置副本集的时候会需要辅助文件hosts.conf. 说明:该示例为一主一丛 ...
- Spring AOP基本概念
Spring AOP基本概念 目录 Spring AOP定义 AOP基本术语 通知类型 AOP定义 AOP基本术语 切面( Aspect ):一个能横切多个对象的模块化的关注点.对Spring AOP ...
- 使用 Eclipse PhoneGap 构建 Android 应用程序入门
Eclipse 是一种支持多种技术的开源集成开发环境 (IDE),但本文重点介绍 Java 支持,这也是 Android 应用程序的“母语”.Android 是 Google 发布的开源移动操作系统. ...
- PHP干货技巧文,一些PHP性能的优化
PHP优化对于PHP的优化主要是对php.ini中的相关主要参数进行合理调整和设置,以下我们就来看看php.ini中的一些对性能影响较大的参数应该如何设置. # vi /etc/php.ini (1) ...
- solr全文检索原理及solr5.5.0 Windows部署
文章原理链接:http://blog.csdn.net/xiaoyu411502/article/details/44803859 自己稍微总结:全文检索主要有两个过程:创建索引,搜索索引 创建索引: ...
- Docker简明教程(转)
Docker自从诞生以来就一直备受追捧,学习Docker是一件很炫酷.很有意思的事情.我希望通过这篇文章能够让大家快速地入门Docker,并有一些学习成果来激发自己的学习兴趣.我也只是一个在Docke ...
- Jmail组件-----发送email
jmail是一个第三方邮件操作组件,通常位于web服务器端,和站点程序紧密配合来接收及提交邮件到邮件服务器的控件,让网站拥有发送邮件既接收邮件的功能. 之所以想尝试它的理由呢 是因为----jmail ...
- UML 类图常用表示方法.
UML中类图实例 接口:空心圆+直线(唐老鸭类实现了‘讲人话’): 依赖:虚线+箭头(动物和空气的关系): 关联:实线+箭头(企鹅需要知道气候才迁移): 聚合:空心四边形+实线+箭头(雁群和大雁的关系 ...
- Swift运算符
运算符分类 运算符分类 一元运算符 1.负号运算符 var number1 = var number2 = -number1 2.正号运算符 //正号运算符不做任何操作 var number3 = + ...
- Man——send(2)翻译
##纯手打 Man——send(2) -->NAME: send, sendto, sendmsg - 在socket上发送一条消息 -->总览: #include <sys/typ ...