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. KingShard MySQL中间件快速入门
  2. ibm服务器imm管理方式简介
  3. 让小程序在自有App中启动的技术来了:mPaaS小程序架构深度解析
  4. GNU make 与 override指令
  5. 中小企业邮件系统选型攻略
  6. 限时秒杀┃秒杀90%的玩具,让孩子爱上科学的彩虹实验2来了!
  7. hdu - 2667 Proving Equivalences(强连通)
  8. JavaScript 和 Java 有关系吗?
  9. python修改excel内容怎么覆盖_Python修改Excel的内容,python,excel
  10. PHP清除HTML代码、空格、回车换行符的函数
  11. _软件园三期西片区F地块举行招商推介会 超300家企业意向落户 - 本网原创
  12. linux调度器(一)——概述
  13. 关于火狐浏览器国际版和国内版的说明
  14. CCC与Android交互的注意点
  15. 开源网上商城程序(简介国内外开源网店系统)
  16. 2022年全球与中国超快激光器市场现状及未来发展趋势
  17. github是什么,有什么用
  18. 学习【Cesium】第六篇,Cesium地图点云与地形的加载(学不会揍我)
  19. 以梦为马之89c51单片机精确1s时间LED灯闪烁(中断技术+定时/计数器技术)
  20. 或许微软真的错了,全端 App 的时代要到来了

热门文章

  1. 计算机编程英文术语,计算机编程英语词汇
  2. java 进入catch,JAVA + try catch(FileNotFoundException e)进入catch(Exception e)?
  3. innodb一页为什么要存储两行记录_innodb数据记录存储结构
  4. 基于wifi的单片机无线通信研究_SKYLAB:智能家居无线协议WiFi/BLE/Zigbee介绍与对比...
  5. Hadoop 单机版和伪分布式版安装
  6. 移动端项目开发需要注意的问题
  7. 参考滴滴左右对齐自适应
  8. Arduino 各种模块篇 motor shield
  9. AS3.0 正则表达式规则
  10. POJ1696 Space Ant