C++代码
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
在学习内存池的过程中可谓云游太虚。一般都是针对标准内存池再次实现。大部分以链表的形式讨论。诚然最正宗也最准确,但是相对比较晦涩,本文是针对刚刚接触内存池的同学写的。大大减少了对内存池整体认识的难度。
  
内存池:
如果程序中涉及频繁申请释放内存,并且每次使用的内存并不是很大,这时候应该考虑内存池。
内存池可以有有效的避免内存碎片的产生。
内存池的框架:
class MemPool{
public:
MemPool(){初始化分配N个小的内存块}
~MemPool(){真正删除整个分配了的内存空间}
void* getmem(){获取内存(块)}
void freemem(){释放内存到内存池中,这里并不是真正的释放掉内存,只是回收再利用;}
private:
struct LinkBlock * p;//把很多小内存块关联起来的结构,大部分写成链表的形式
mem_block* m_block;//一个小的内存块。
};
工作机制:
事先分配出一大块内存,再把这一大块分成很多小块。当程序中需要申请内存时就拿出一小块来用。用完了就把这一小块放回大块中(注意:这个小块内存并没释放掉!),只要不是一下用掉了所有一大块内存,无论多少次申请内存都是重复利用这些小的内存块。知道程序结束真正释放掉整片内存。
所以用内存池可以把大量的内存申请控制在可计算的范围内。内存碎片少。比如:如果用系统的new或者malloc申请10000次内存,可能要10000的小的内存空间,但是使用内存池只需申请100块空间,循环利用100次而已。作用显而易见!
  
为了让程序简单明了使用STL标准库的vector来充当小内存块的管理器。
vector<char*> vec; 这样每次申请的是vec的一个迭代器的空间。
  
代码非原创,稍稍做了改动而已。
========================================================================
MemPool.h
  
#ifndef _MEM_POOL_H   
#define _MEM_POOL_H    
#include <vector>   
#include <iostream>   
using namespace std;  
  
/* 
    在内存池中分配固定大小的内存块  
    目的是加速内存分配速度,并且减少因重复分配相同  
*/  
  
class CMemPool  
{  
public:  
      
    //创建大小为blockSize的内存块,内存池数目为预分配的数目preAlloc   
    CMemPool(int blockSize, int preAlloc = 0, int maxAlloc = 0);  
      
    ~CMemPool();  
      
    //获取一个内存块。如果内存池中没有足够的内存块,则会自动分配新的内存块   
    //如果分配的内存块数目达到了最大值,则会返回一个异常   
    void* Get();  
      
    //释放当前内存块,将其插入内存池   
    void Release(void* ptr);  
      
    //返回内存块大小   
    int BlockSize() const;  
      
    //返回内存池中内存块数目   
    int Allocated() const;  
      
    //返回内存池中可用的内存块数目   
    int Available() const;  
      
private:  
    CMemPool();  
    CMemPool(const CMemPool&);  
    CMemPool& operator = (const CMemPool&);  
      
    enum  
    {  
        BLOCK_RESERVE = 128  
    };  
      
    typedef std::vector<char*> BlockVec;  
      
    int m_blockSize;  
    int         m_maxAlloc;  
    int         m_allocated;  
    BlockVec    m_blocks;  
};  
  
inline int CMemPool::BlockSize() const  
{  
    return m_blockSize;  
}  
  
inline int CMemPool::Allocated() const  
{  
    return m_allocated;  
}  
  
inline int CMemPool::Available() const  
{  
    return (int) m_blocks.size();  
}  
#endif  
  
=========================================================
MemPool.cpp
  
  
#include "MemPool.h"   
CMemPool::CMemPool(int blockSize, int preAlloc, int maxAlloc):  
m_blockSize(blockSize),  
m_maxAlloc(maxAlloc),  
m_allocated(preAlloc)  
{  
    if ( preAlloc < 0 || maxAlloc == 0 || maxAlloc < preAlloc )  
    {  
        cout<<"CMemPool::CMemPool parameter error."<<endl;  
    }  
      
    int r = BLOCK_RESERVE;  
    if (preAlloc > r)  
        r = preAlloc;  
    if (maxAlloc > 0 && maxAlloc < r)  
        r = maxAlloc;  
    m_blocks.reserve(r);  
    for (int i = 0; i < preAlloc; ++i)  
    {  
        m_blocks.push_back(new char[m_blockSize]);  
    }  
}     
CMemPool::~CMemPool()  
{  
    for (BlockVec::iterator it = m_blocks.begin(); it != m_blocks.end(); ++it)  
    {  
        delete [] *it;  
    }  
}  
  
void* CMemPool::Get()  
{    
      
    if (m_blocks.empty())  
    {  
        if (m_maxAlloc == 0 || m_allocated < m_maxAlloc)  
        {  
            ++m_allocated;  
            return new char[m_blockSize];  
        }  
        else  
        {  
            cout<<"CMemPool::get CMemPool exhausted."<<endl;  
            return (void *)NULL;  
        }  
    }  
    else  
    {  
        char* ptr = m_blocks.back();  
        m_blocks.pop_back();  
        return ptr;  
    }  
}  
  
  
void CMemPool::Release(void* ptr)  
{   
    memset(ptr,0,sizeof(char)*m_blockSize);//内存回收回来以后并没销毁,原数据仍在,所以应该清空
    m_blocks.push_back(reinterpret_cast<char*>(ptr));  
}   
  
=========
main.h
  
#include "stdafx.h"
#include "MemPool.h"
#include <string.h>
int main(int argc, char* argv[])
{
CMemPool *m_cache =new CMemPool(50,0,10);
  
char * src_date="abcdefg";
char *p1=(char*)(m_cache->Get());
char *p2=(char*)(m_cache->Get());
int *p3=(int*)(m_cache->Get());
strcpy(p1,src_date);
strcpy(p2,src_date);
p3[0]=9;p3[1]=25;
  
m_cache->Release(p1);
m_cache->Release(p2);
m_cache->Release(p3);
  
//把MemPool.cpp中void CMemPool::Release(void* ptr) 的
//memset(ptr,0,sizeof(char)*m_blockSize);注释掉可以验证每次内存回收以后是重复利用而非销毁
cout<<*(int*)(m_cache->Get())<<endl;
cout<<(char*)(m_cache->Get())<<endl;
cout<<(char*)(m_cache->Get())<<endl;
delete m_cache;
    return 0;
}
  
完毕!
  
当然这只是探究内存池而已,更高级的比如线程安全,内存扩容,模板等等,仍需解决。
但是相信想初窥内存池门径应该还是有帮助的!

描述:以STL-vector为数据存储单元,实现简单的内存池功能。

(转载)简单linux C++内存池相关推荐

  1. linux boost内存池,C++ boost库教程之内存池

    Boost  Pool 库提供了一个内存池分配器,它是一个工具,用于管理在一个独立的.大的分配空间里的动 态内存.当你需要分配和回收许多不的对象或需要更高效的内存控制时,使用内存池是一个好的 解决方案 ...

  2. 当Java虚拟机遇上Linux Arena内存池

    作者简介 刘韬,云和恩墨中间件服务交付团队专家 Java开发出身,10年WebLogic相关开发.运维工作经验,熟悉SOA.现代业务系统架构中各层组件,尤其擅长故障处理.性能优化等工作. 故障案例一 ...

  3. 源码分享:C++矩阵类CLMatrixT,功能强大使用简单,支持内存池、宽指令、并行化加速!持续更新...

    CLMatrixT文档目录: C++矩阵类模板CLMatrixT介绍: 特点 新增功能 先演示使用方法: 再看运行测试结果: 最后分享源代码: C++矩阵类模板CLMatrixT介绍: 最近在研究AI ...

  4. linux boost内存池,开源C++函数库Boost内存池使用与测试

    [IT168 专稿]Boost库是一个可移植的开源C++函数库,鉴于STL(标准模板库)已经成为C++语言的一个组成部分,可以毫不夸张的说,Boost是目前影响最大的通用C++库.Boost库由C++ ...

  5. 简单Linux C线程池

    大多数的网络服务器,包括Web服务器都具有一个特点,就是单位时间内必须处理数目巨大的连接请求,但是处理时间却是比较短的.在传统的多线程服务器模型中是这样实现的:一旦有个请求到达,就创建一个新的线程,由 ...

  6. C++ 应用程序性能优化,第 6 章:内存池

    引言 本书主要针对的是 C++ 程序的性能优化,深入介绍 C++ 程序性能优化的方法和实例.全书由 4 个篇组成,第 1 篇介绍 C++ 语言的对象模型,该篇是优化 C++ 程序的基础:第 2 篇主要 ...

  7. C++11实现高效内存池

    C++11实现高效内存池 前言 项目介绍 内存池是什么 allocator详解 MemoryPool.tcc allocateBlock 创建Block块 padPointer 空间对齐 Memory ...

  8. Linux:C GNU Obstack内存池

    目录 wiki对obstack的介绍 GNU C的Obstack描述 Obstack初始化 在Obstack里面申请对象 释放Obstack里面的对象 可增长内存空间的对象 Obstack 的状态 O ...

  9. linux内存管理(十五)-内存池

    一.内存池原理 平时我们直接所使用的 malloc,new,free,delete 等等 API 申请内存分配,这做缺点在于,由于所申请内存块的大小不定,当频繁使用时会造成大量的内存碎片并进而降低性能 ...

最新文章

  1. 一个 Mybatis 开发神器:Fast MyBatis 超好用
  2. easyui框架前后端交互_easyui前后端分离
  3. JSP与Servelt的区别
  4. phoengap–node+websocket在线聊天室
  5. 一至七-----小东西
  6. 教师要合理使用计算机,教师学习计算机应用基础总结
  7. realtek网卡mac硬改工具_七彩虹联合Realtek发布粉色固态硬盘 首发评测
  8. 学.net还是php,ASP.NET和php哪个更容易学
  9. 运算符和||运算符的优先级问题 专题
  10. MySQL------报错Access denied for user ‘root‘@‘localhost‘ (using password:NO)解决方法
  11. 销售行业ERP数据统计分析都有哪些维度?
  12. x86 服务器常见问题和故障诊断流程
  13. 女友的一个建议,让26岁程序员做了个价值 10 亿美元的 App
  14. 第六次团队作业+登录界面
  15. 各行各业有对象系列之三:对象存储与银行
  16. schema约束和引入
  17. Eclipse集成Zxing实现扫一扫功能
  18. win11java环境配置
  19. 笔记本ubuntu安装xen之殇
  20. sRGB HDR概念性学习

热门文章

  1. javascript 权威指南第7版_免费领书 | 气相色谱与质谱实用指南(原著第2版)
  2. 微信小程序调用php,微信小程序调用PHP后台接口 解析纯html文本
  3. openstack云主机无法绑定ip_智汇华云|OpenStack 虚拟机 GPU 性能优化
  4. python什么是调用_python open需要调用什么
  5. 排序命令: sort, wc, uniq
  6. openssh实现key验证免密码登录
  7. java设计模式简述
  8. JS实现图片的不间断连续滚动
  9. 抽象SQL查询:SQL-MAP技术的使用
  10. MM--移动类型的配置相关的系统表,举例说明SAP是如何根据配置抛帐的