(转载)简单linux C++内存池
来源:互联网 发布:mac怎么点亮键盘 编辑:程序博客网 时间:2024/05/21 11:16
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++内存池
- 简单linux C++内存池
- linux下Epoll实现简单的C/S通信(转载)
- linux c 实现内存池
- 发个简单(易用)的内存池(转载)
- 发个简单(易用)的内存池(转载)
- Objective-C内存管理【转载】
- object c内存管理转载
- object c内存管理转载
- C 内存分配(转载)
- object c内存管理转载
- C 内存分配(转载)
- c/C++内存分配(转载)
- C中内存堆栈的布局---linux 简单实例
- linux下c检查内存泄漏的简单方法
- 内存池的简单试验(C++)
- 内存池的简单试验(C++)
- 内存池的简单试验(C++)
- POJ 1008 结题报告
- Eclipse中如何修改SVN的地址
- Java菜鸟学习笔记--面向对象篇(八):成员变量和局部变量
- 【互动话题】如何赚外快?
- Maven中的WEB工程转换为MyEclipse中的WEB工程(自动部署,调试)
- (转载)简单linux C++内存池
- Oracle_处理数据
- python列表排序
- grails自动创建MYSQL数据库字符集设置utf8
- proxool 数据库工具使用
- 电影记忆之16(人工智能)
- HTML5 Web SQL Database 数据库的使用方法
- hdu 还是畅通工程
- 删除windows默认共享