-
Notifications
You must be signed in to change notification settings - Fork 0
/
log_boost_pool.html
166 lines (131 loc) · 4.88 KB
/
log_boost_pool.html
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
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<!--
<link rel="icon" href="../../../../favicon.ico">
-->
<title>boost::pool与内存池技术</title>
<style type="text/css">
pre {
white-space: pre-wrap;
word-wrap: break-word;
}
</style>
<!-- Bootstrap core CSS -->
<link href="https://cdn.bootcss.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="./sticky-footer.css" rel="stylesheet">
</head>
<body>
<!-- Begin page content -->
<main role="main" class="container">
<h1 class="mt-5">boost::pool与内存池技术</h1>
<a href="http://blog.csdn.net/xushiweizh/archive/2006/11/21/1400426.aspx">本文参考</a>
<p></p>
<p>
<pre>
Pool分配是一种分配内存方法,用于快速分配同样大小的内存块,
尤其是反复分配/释放同样大小的内存块的情况。
1. pool
快速分配小块内存,如果pool无法提供小块内存给用户,返回0。
Example:
void func()
{
boost::pool<> p(sizeof(int));
指定每次分配的块的大小
for (int i = 0; i < 10000; ++i)
{
int * const t = p.malloc();
pool分配指定大小的内存块;需要的时候,pool会向系统
申请大块内存。
... // Do something with t; don't take the time to free() it
p.free( t );
// 释放内存块,交还给pool,不是返回给系统。
}
pool的析构函数会释放所有从系统申请到的内存。
2. object_pool
与pool的区别在于:pool需要指定每次分配的块的大小,object_pool需要指定
每次分配的对象的类型。
pool只释放内存,不调用对象的析构函数。
Example:
struct X { ... }; // has destructor with side-effects
void func()
{
boost::object_pool<X> p;
for (int i = 0; i < 10000; ++i)
{
X * const t = p.malloc();
注意;X的构造函数不会被调用,仅仅是分配大小为sizeof(X)
的内存块。如果需要调用构造函数(像new一样),应该调用
construct。比如:
X * const t = p.construct();
...
}
}
3. singleton_pool
与pool用法一样。不同的是:可以定义多个pool类型的object,都是分配同样
大小的内存块;singleton_pool提供静态成员方法分配内存,不用定义object。
Example:
struct MyPoolTag { };
typedef boost::singleton_pool<MyPoolTag, sizeof(int)> my_pool;
void func()
{
for (int i = 0; i < 10000; ++i)
{
int * const t = my_pool::malloc();
// 和pool不一样。
...
}
my_pool::purge_memory();
// 释放my_pool申请的内存。
}
4. pool_alloc
基于singleton_pool实现,提供allocator(用于STL等)。
Example:
void func()
{
std::vector<int, boost::pool_allocator<int> > v;
for (int i = 0; i < 10000; ++i)
v.push_back(13);
}
需要的话,必须自己显式地调用
boost::singleton_pool<boost::pool_allocator_tag, sizeof(int)>::release_memory()
把allocator分配的内存返回系统。
实现原理
pool每次向系统申请一大块内存,然后分成同样大小的多个小块,
形成链表连接起来。每次分配的时候,从链表中取出头上一块,提
供给用户。链表为空的时候,pool继续向系统申请大块内存。
一个小问题:在pool的实现中,在申请到大块内存后,马上把它分
成小块形成链表。这个过程开销比较大。即你需要分配一小块内存
时,却需要生成一个大的链表。用如下代码测试:
boost::pool<> mem_pool(16);
for(i = 0; i < NPASS; i++) {
period = clock();
for(n = 0; n < NITEM; n++) {
array_ptr[n] = (int *)mem_pool.malloc();
}
for(n = 0; n < NITEM; n++) {
mem_pool.free(array_ptr[n]);
}
period = clock() - period;
printf("pool<> : period = %5d ms ", period);
}
可以发现,第一遍花的时间明显多于后面的。
而且在pool的使用过程中如果不是恰好把链表中所有的小块都用上
的话,在链表中最后的一些小块会始终用不上。把这些小块加入链
表是多余的。虽然这个开销可能很小:)
</pre>
</p>
</main>
<footer class="footer">
<div class="container">
<span class="text-muted"> Kero~ </span>
<h2><a href="./index.html">Home</a></h2>
</div>
</footer>
</body>
</html>