开源C++函数库Boost内存池使⽤与测试
转⾃:
【IT168 专稿】Boost库是⼀个可移植的开源C++函数库,鉴于STL(标准模板库)已经成为C++语⾔的⼀个组成部分,可以毫不夸张的
说,Boost是⽬前影响最⼤的通⽤C++库。Boost库由C++标准委员会库⼯作组成员发起,其中有些内容有望成为下⼀代C++标准库内容,是⼀个“准”标准库。
Boost内存池,即boost.pool库,是由Boost提供的⼀个⽤于内存池管理的开源C++库。作为Boost中影响较⼤的⼀个库,Pool已经被⼴泛使⽤。
1. 什么是内存池
“池”是在计算机技术中经常使⽤的⼀种设计模式,其内涵在于:将程序中需要经常使⽤的核⼼资源先申请出来,放到⼀个池内,由程序⾃⼰管理,这样可以提⾼资源的使⽤效率,也可以保证本程序占有的资源数量。经常使⽤的池技术包括内存池、线程池和连接池等,其中尤以内存池和线程池使⽤最多。
内存池(Memory Pool)是⼀种动态内存分配与管理技术。通常情况下,程序员习惯直接使⽤new、delet
e、malloc、free等API申请分配和释放内存,导致的后果时:当程序长时间运⾏时,由于所申请内存块的⼤⼩不定,频繁使⽤时会造成⼤量的内存碎⽚从⽽降低程序和操作系统的性能。内存池则是在真正使⽤内存之前,先申请分配⼀⼤块内存(内存池)留作备⽤,当程序员申请内存时,从池中取出⼀块动态分配,当程序员释放内存时,将释放的内存再放⼊池内,并尽量与周边的空闲内存块合并。若内存池不够时,则⾃动扩⼤内存池,从操作系统中申请更⼤的内存池。
内存池的应⽤场景
早期的内存池技术是为了专门解决那种频繁申请和释放相同⼤⼩内存块的程序,因此早期的⼀些内存池都是⽤相同⼤⼩的内存块链表组织起来的。
Boost的内存池则对内存块的⼤⼩是否相同没有限制,因此只要是频繁动态申请释放内存的长时间运⾏程序,都适⽤Boost内存池。这样可以有效减少内存碎⽚并提⾼程序运⾏效率。
安装
Boost的pool库是以C++头⽂件的形式提供的,不需要安装,也没有lib或者dll⽂件,仅仅需要将头⽂件包含到你的C++⼯程中就可以了。Boost的最新版本可以到/下载。
2. 内存池的特征
2.1 ⽆内存泄露
正确的使⽤内存池的申请和释放函数不会造成内存泄露,更重要的是,即使不正确的使⽤了申请和释放函数,内存池中的内存也会在进程结束时被全部⾃动释放,不会造成系统的内存泄露。
2.2 申请的内存数组没有被填充
例如⼀个元素的内存⼤⼩为A,那么元素数组若包含n个元素,则该数组的内存⼤⼩必然是A*n,不会有多余的内存来填充该数组。尽管每个元素也许包含⼀些填充的东西。
2.3 任何数组内存块的位置都和使⽤operator new[]分配的内存块位置⼀致
这表明你仍可以使⽤那些通过数组指针计算内存块位置的算法。
molloc函数 2.4 内存池要⽐直接使⽤系统的动态内存分配快
这个快是概率意义上的,不是每个时刻,每种内存池都⽐直接使⽤new或者malloc快。例如,当程序使⽤内存池时内存池恰好处于已经满了的状态,那么这次内存申请会导致内存池⾃我扩充,肯定⽐直接new⼀块内存要慢。但在⼤部分时候,内存池要⽐new或者malloc快很多。
3. 内存池效率测试
3.1 测试1:连续申请和连续释放
分别⽤内存池和new连续申请和连续释放⼤量的内存块,⽐较其运⾏速度,代码如下:
测试环境:VS2008,WindowXP SP2,Pentium 4 CPU双核,1.5GB内存。
结论:在连续申请和连续释放10万块内存的情况下,使⽤内存池耗时是使⽤new耗时的47.46%。
3.2 测试2:反复申请和释放⼩块内存
代码如下:
测试结果如下:
结论:在反复申请和释放50万次内存的情况下,使⽤内存池耗时是使⽤new耗时的64.34%。
3.3 测试3:反复申请和释放C++对象
C++对象在动态申请和释放时,不仅要进⾏内存操作,同时还要调⽤构造和析购函数。因此有必要对C++对象也进⾏内存池的测试。 代码如下:
测试结果如下:
结论:在反复申请和释放50万个C++对象的情况下,使⽤内存池耗时是使⽤new耗时的112.03%。这是因为内存池的construct和destroy 函数增加了函数调⽤次数的原因。这种情况下使⽤内存池并不能获得性能上的优化。
4. Boost内存池的分类
Boost内存池按照不同的理念分为四类。主要是两种理念的不同造成了这样的分类。
⼀是Object Usage和Singleton Usage的不同。Object Usage意味着每个内存池都是⼀个可以创建和销毁的对象,⼀旦内存池被销毁则其所分配的所有内存都会被释放。Singleton Usage意味着每个内存
池都是⼀个被静态分配的对象,直⾄程序结束才会被销毁,这也意味着这样的内存池是多线程安全的。只有使⽤release_memory或者 purge_memory⽅法才能释放内存。
⼆是内存溢出的处理⽅式。第⼀种⽅式是返回NULL代表内存池溢出了;第⼆种⽅式是抛出异常代表内存池溢出。
根据以上的理念,boost的内存池分为四种。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论