谁能推荐好的内存池源代码,c语言坦克大战源代码的

博客访问: 214623
博文数量: 81
博客积分: 1270
博客等级: 中尉
技术积分: 1370
注册时间:
freedom~~~~~~~~~~
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: 嵌入式
头文件:_mem_pool.h//define the data structures here
typedef struct _list_node
&&&&void *addr;
&&&&struct _list_node *next_node;
}list_node;
typedef struct _manager_node
&&&&list_node *start_node;
&&&&list_node *last_node;
&&&&unsigned int addr_start;
&&&&unsigned int addr_end;
&&&&int node_num;
&&&&int available_num;
}manager_node;
manager_node manager_list[3];
list_node list_8_node[400];
list_node list_16_node[200];
list_node list_32_node[100];
#define assert_param(param) &&&& &&&&if(param==NULL) return 0;_mem_pool.c#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include "_mem_pool.h"
list_node *available[3];
list_node *rear[3];
extern manager_node &&&&manager_list[3];
extern list_node
&&&&list_8_node[400];
extern list_node &&&&list_16_node[200];
extern list_node &&&&list_32_node[100];
int count = 0;
typedef list_node* (*init_ptr) (list_node **);
list_node * eight_init(list_node **last)
&&&&void *a = malloc(8*400);
&&&&printf("the list8 start addr is %x\n",(int)a);
&&&&int i;
&&&&assert_param(a);
&&&&for(i=0;i<400;i++)
&&&&&&&&list_8_node[i].addr=a+i*8;
&&&&&&&&list_8_node[i].next_node=NULL;
&&&&&&&&//printf("the list %d addr is
%x\n",i,(int)(list_8_node[i].addr));
&&&&&&&&if(i==399)
&&&&&&&&&&&&break;
&&&&&&&&list_8_node[i].next_node=&list_8_node[i+1];
&&&&*last=&(list_8_node[i]);
&&&&printf("the list8 node %dend addr is %x\n\n",i,(int)(list_8_node[i].addr));
&&&&return (&list_8_node[0]);
list_node * sixteen_init(list_node **last)
&&&&void *a = malloc(16*400);
&&&&printf("the list16 start addr is %x\n",(int)a);
&&&&int i;
&&&&assert_param(a);
&&&&for(i=0;i<400;i++)
&&&&&&&&list_16_node[i].addr=a+i*16;
&&&&&&&&list_16_node[i].next_node=NULL;
&&&&&&&&//printf("the list %d addr is
%x\n",i,(int)(list_16_node[i].addr));
&&&&&&&&if(i==199)
&&&&&&&&&&&&break;
&&&&&&&&list_16_node[i].next_node=&list_16_node[i+1];
&&&&*last=&(list_16_node[i]);
&&&&printf("the list16 node %dend addr is %x\n\n",i,(int)(list_16_node[i].addr));
&&&&return (&list_16_node[0]);
list_node * thirtytwo_init(list_node **last)
&&&&void *a = malloc(32*100);
&&&&printf("the list32 start addr is %x\n",(int)a);
&&&&int i;
&&&&assert_param(a);
&&&&for(i=0;i<100;i++)
&&&&&&&&list_32_node[i].addr=a+i*32;
&&&&&&&&list_32_node[i].next_node=NULL;
&&&&&&&&//printf("the list %d addr is
%x\n",i,(int)(list_32_node[i].addr));
&&&&&&&&if(i==99)
&&&&&&&&&&&&break;
&&&&&&&&list_32_node[i].next_node=&list_32_node[i+1];
&&&&*last=&(list_32_node[i]);
//&&&&printf("%x++++++++++++++\n",(int)((*last)->addr));
&&&&printf("the list32 node %dend addr is %x\n\n",i,(int)(list_32_node[i].addr));
&&&&return (&list_32_node[0]);
init_ptr func_ptr[]=
&&&&eight_init,
&&&&sixteen_init,
&&&&thirtytwo_init,
int mem_pool_init()
&&&&int i;
&&&&for(i=0;i<3;i++)
&&&&&&&&available[i]=(*func_ptr[i])(&(rear[i]));
&&&&for(i=0;i<3;i++)
&&&&&&&&manager_list[i].start_node=available[i];&&&&&&&&&&&&
&&&&&&&&manager_list[i].last_node=rear[i];
&&&&&&&&manager_list[i].addr_start=(unsigned int)(available[i]->addr);
&&&&&&&&manager_list[i].addr_end=(unsigned int)(manager_list[i].last_node->addr);
&&&&&&&&printf("the manager_list[%d] \tstart addr is%x and end addr is %x\n\n",i,(unsigned int)(unsigned int)(manager_list[i].start_node->addr),(unsigned int)(manager_list[i].last_node->addr));
void * mem_alloc(int num)
&&&&int i;
&&&&if(num>=1&&num<=8)
&&&&&&&&i=0;
&&&&else if(num>=9&&num<=16)
&&&&&&&&i=1;
&&&&else if(num>=17&&num<=32)
&&&&&&&&i=2;
&&&&&&&&return (malloc(num));
&&&&if(manager_list[i].start_node == NULL)
&&&&&&&&printf("this is no space in mempool!!");
&&&&&&&&return (malloc(num));
&&&&list_node *p=manager_list[i].start_node;
&&&&manager_list[i].start_node = manager_list[i].start_node->next_node;
&&&&p->next_node=NULL;
&&&&return (p->addr);
void mem_free(void *addr)
&&&&if(addr==NULL)
&&&&&&&&return ;
&&&&int i;
&&&&unsigned int num=(unsigned int)(addr);
&&&&unsigned int start_addr,end_addr;
&&&&for(i=0;i<3;i++)
&&&&&&&&start_addr=(unsigned int)available[i]->addr;
&&&&&&&&end_addr=(unsigned int)rear[i]->addr;
&&&&&&&&if(num>=start_addr&&num<=end_addr)
&&&&&&&&break;
//&&&&printf("the free add is %x and the start addr is %x\n",num,start_addr);
&&&&num=(num-start_addr)/(8*(i+1));
&&&&if(num>400)
&&&&&&&&return;
//&&&&printf("the free node is %d\tand is nodelist[%d]\n",num,i);
&&&&switch(i)
&&&&&&&&case 0:
//&&&&&&&&&&&&printf("list_8_node[%d] the next is %x\n",num,list_8_node[num].next_node);
&&&&&&&&&&&&list_8_node[num].next_node=manager_list[i].start_node;
&&&&&&&&&&&&manager_list[i].start_node=&(list_8_node[num]);
&&&&&&&&&&&&break;
&&&&&&&&case 1:
//&&&&&&&&&&&&printf("list_16_node[%d] the next is %x\n",num,list_16_node[num].next_node);
&&&&&&&&&&&&list_16_node[num].next_node=manager_list[i].start_node;
&&&&&&&&&&&&manager_list[i].start_node=&(list_16_node[num]);
&&&&&&&&&&&&break;
&&&&&&&&case 2:
//&&&&&&&&&&&&printf("list_32_node[%d] the next is %x\n",num,list_32_node[num].next_node);
&&&&&&&&&&&&list_32_node[num].next_node=manager_list[i].start_node;
&&&&&&&&&&&&manager_list[i].start_node=&(list_32_node[num]);
&&&&&&&&&&&&break;
&&&&&&&&default:
&&&&&&&&&&&&free(addr);
&&&&&&&&&&&&break;
int main()
&&&&mem_pool_init();
&&&&int i;
&&&&void *a;
&&&&void *b;
&&&&for(i=0;i<1000;i++)
&&&&&&&&a=mem_alloc(5);
&&&&&&&&printf("+++++++++++++++the %d addr is %x\n",i,(unsigned int)a);
&&&&&&&&i++;&&&&&&&&
&&&&&&&&b=mem_alloc(5);
&&&&&&&&printf("+++++++++++++++the %d addr is %x\n",i,(unsigned int)b);
&&&&&&&&mem_free(a);
&&&&&&&&mem_free(b);
&&&&for(i=0;i<1000;i++)
&&&&&&&&a=mem_alloc(18);
&&&&&&&&printf("+++++++++++++++the %d addr is %x\n",i,(unsigned int)a);
&&&&&&&&i++;&&&&&&&&
&&&&&&&&b=mem_alloc(18);
&&&&&&&&printf("+++++++++++++++the %d addr is %x\n",i,(unsigned int)b);
&&&&&&&&mem_free(a);
&&&&&&&&mem_free(b);
&&&&for(i=0;i<1000;i++)
&&&&&&&&a=mem_alloc(10);
&&&&&&&&printf("+++++++++++++++the %d addr is %x\n",i,(unsigned int)a);
&&&&&&&&i++;&&&&&&&&
&&&&&&&&b=mem_alloc(10);
&&&&&&&&printf("+++++++++++++++the %d addr is %x\n",i,(unsigned int)b);
&&&&&&&&mem_free(a);
&&&&&&&&mem_free(b);
&&&&printf("the mem alloc is %x\n",(int)a);
&&&&//mem_free(a);
&&&&a=mem_alloc(9);
&&&&//printf("the mem alloc 9 ++++++++++++++++++is %x\n",(int)a);
&&&&mem_free(a);
&&&&a=mem_alloc(18);
&&&&printf("the mem alloc is %x\n",(int)a);
&&&&a=mem_alloc(100);
&&&&free(a);
&&&&clock_t t1,t2,ta,tb;
&&&&t1=clock();
&&&&int t;
&&&&for(t=0;t<0x0ffffffa;t++)
&&&&&&&&a=mem_alloc(5);
&&&&&&&&mem_free(a);
&&&&t2=clock();
&&&&ta=t2-t1;
&&&&t1=clock();
&&&&for(t=0;t<0x0ffffffa;t++)
&&&&&&&&a=malloc(5);
&&&&&&&&free(a);
&&&&t2=clock();
&&&&tb=t2-t1;
&&&&printf("the time %ld\t%ld\n",ta,tb);
}makefile文件:all: &&&&test debug
cc=gcc -Wall
&&&&@$(cc) _mem_pool.c -o test.out
&&&&@$(cc) -g _mem_pool.c
-o test.gdb测试了一下,和系统的直接分配时间比大概是6:9
阅读(3343) | 评论(0) | 转发(1) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。C语言实现内存池
C语言实现内存池
发布时间: 13:22:56
编辑:www.fx114.net
本篇文章主要介绍了"C语言实现内存池",主要涉及到C语言实现内存池方面的内容,对于C语言实现内存池感兴趣的同学可以参考一下。
什么是内存池,这里简单介绍一下(不做详细说明),内存池技术是一种用于分配大量大小相同的小对象的技术,通过该技术可以极大加快内存分配/释放过 程。其原理是先申请一大块内存,然后分成若干个大小相等的小块,用链表的方式将这些小块链在一起,当开发人员需要使用内存时(分配),从链表头取下一块返 回给开发人员使用;当开发人员使用完毕后(释放),再将这块内存重新挂回链表尾。这样操作的好处有如下三点:1、提高分配和释放的效率;2、避免开发人员 忘记释放内存造成内存泄露;3、减少内存占用(频繁的malloc是很占内存空间的,至于为什么我就不说了,可以到网上搜索内存管理相关的内容);
关于内存池技术的代码在网上也有不少,我也看过一些,有基于C现实的,也有C&#43;&#43;实现的,但在这些文章里都发现两个问题,1、当开发人员使用完内存 后,如果不释放,那么还是会有内存泄露的情况;2、在开发人员使用完内存后,释放的时候总会去循环判断该地址是否存在,在这种情况下,释放的效率并有没有 得到提升。
那么如何解决这两个问题呢,我先简单介绍一下我这个内存池,先看段结构体:
[cpp] view plain
typedef struct _memory_pool
unsigned int blockC//申请块数量
unsigned int blockCountS//内存块数增长步长
unsigned int blockS//单个块的大小
unsigned int freeC//空闲的内存块数
MemoryBlock *freeH //空闲的头
MemoryBlock *freeT //空闲的尾
MemoryBlock *usedH //已使用的头
MemoryBlock *usedT //已使用的尾
char *pBlockMemoryH //块的头指针,用于释放内存时候用(因为块的分配了一大块的内存)
char *pDataMemoryH//数据区域头指针
这里面描述了详细存放信息,当池初始化时,所有块都存在空闲块中,已使用块为空,当申请一块空间时,从空闲块的头取下来放到已使用的块中,基本过程 就是这样子的。下面来解决上面提到的两个问题,1、在内存泄露方面,先申请两大块的连续空间,一块用于存放块的基本信息(块链表),另一块返回给开发人员 使用(数据区域),然后用指针保存两块内存地址,这样一来,不管你是否释放,在程序需要清理内存的时候,我只需要free两次;2、在释放效率方面,我们 不使用循环方式来处理,而是在返回给开发人员使用的内存块前面加4个字节存放与他关联的块信息块地址,在释放的时候,我们只需要(MemoryBlock
*)((char *)ptr – 4)就能得到块地址,这样就很方便的挂回空闲块。具体现实代码如下:
[cpp] view plain
#include &stdio.h&
#include &malloc.h&
#include &string.h&
typedef struct _memory_block
struct _memory_block *pN //下一个内存单元
struct _memory_block *pP //上一个内存单元
char* //数据,
typedef struct _memory_pool
unsigned int blockC//申请块数量
unsigned int blockCountS//内存块数增长步长
unsigned int blockS//单个块的大小
unsigned int freeC//空闲的内存块数
MemoryBlock *freeH //空闲的头
MemoryBlock *freeT //空闲的尾
MemoryBlock *usedH //已使用的头
MemoryBlock *usedT //已使用的尾
char *pBlockMemoryH //块的头指针,用于释放内存时候用(因为块的分配了一大块的内存)
char *pDataMemoryH//数据区域头指针
int Xpool_init(unsigned int blockCount, unsigned int blockSize);
int Xpool_destroy(void);
void* Xpool_alloc(unsigned int size);
int Xpool_free(void *ptr);
static int Xpool_block(unsigned int blockCount, unsigned int blockSize);
static MemoryP
//初始化内存池
int Xpool_init(unsigned int blockCount, unsigned int blockSize)
MemoryPool *p = &
p-&blockCount = blockC
p-&blockSize = blockS
p-&freeCount = blockC
p-&blockCountStep = 100;
p-&freeHead = p-&freeTail = NULL;
p-&usedHead = p-&usedTail = NULL;
Xpool_block(blockCount, blockSize);
//申请块,并且把新申请的块连到空闲块后面
static int Xpool_block(unsigned int blockCount, unsigned int blockSize)
MemoryPool *p = &
MemoryBlock *pFree = NULL;//空闲块连表指针
p-&pBlockMemoryHead = (char *)malloc(sizeof(MemoryBlock) * blockCount);//分配一大块连续的内存块空间存放块信息
p-&pDataMemoryHead = (char *)malloc((blockSize &#43; sizeof(MemoryBlock *)) * blockCount);//分配一大块连续的内存空间存放供用户使用的空间
for(unsigned int i = 0; i & blockC i&#43;&#43;)
pFree = (MemoryBlock *)(p-&pBlockMemoryHead &#43; (sizeof(MemoryBlock) * i));//(MemoryBlock *)malloc(sizeof(MemoryBlock));
pFree-&data = p-&pDataMemoryHead &#43; ((blockSize &#43; sizeof(MemoryBlock *)) * i);//(void *)malloc(blockSize &#43; sizeof(MemoryBlock *));//分配一块数据区域
pFree-&pNext = NULL;
pFree-&pPrev = p-&freeT
if(p-&freeHead == NULL){
p-&freeHead = p-&freeTail = pF
p-&freeTail-&pNext = pF
p-&freeTail = pF
//销毁内存池
int Xpool_destroy(void)
MemoryPool *p = &
//释放内存块所占的内存
free(p-&pBlockMemoryHead);
//释放数据区域所占的内存
free(p-&pDataMemoryHead);
//申请内存
void* Xpool_alloc(unsigned int size)
MemoryPool *p = &
MemoryBlock *block = NULL;
if(p-&freeHead == NULL){//没有可用空间
Xpool_block(p-&blockCountStep, p-&blockSize);
block = p-&freeH//获取表头内存块
p-&freeHead = block-&pN//将空闲块的链表头
p-&freeCount--;//空闲块数量减一
block-&pNext = NULL;
block-&pPrev = p-&usedT//这个块的上个块是已使用块的最后一个块
//第一次使用内存?
if(p-&usedHead == NULL){
p-&usedHead = p-&usedTail =//,则已使用的头和尾都指向这个块
}else{//不是第一次
p-&usedTail-&pNext =
p-&usedTail =
//留下data里一个指针的空间,用于保存与数据关联的块地址
block-&data = (char *)
return (char *)block-&data &#43; sizeof(MemoryBlock *);
//回收内存
int Xpool_free(void *ptr)
MemoryPool *p = &
char *realptr = (char *)ptr - sizeof(MemoryBlock *); //数据块真实的起始地址
MemoryBlock *block = (MemoryBlock *)
if(block == NULL){
return NULL;
if(block-&pPrev == NULL){//如果是头
p-&usedHead = block-&pN
if(p-&usedHead != NULL){
p-&usedHead-&pPrev = NULL;
}else if(block-&pNext == NULL){//如果是尾
p-&usedTail = block-&pP
if(p-&usedTail != NULL){
p-&usedTail-&pNext = NULL;
}else{//中间的
block-&pPrev-&pNext = block-&pN
block-&pNext-&pPrev = block-&pP
//重置参数
block-&pPrev = p-&freeT
block-&pNext = NULL;
block-&data =
//加到空闲块链表
p-&freeTail-&pNext =
p-&freeTail =
p-&freeCount&#43;&#43;;
int main(int argc, char *argv[])
Xpool_init(10, 96);
char *p = (char *)Xpool_alloc(20);
Xpool_free(p);
Xpool_destroy();
一、不得利用本站危害国家安全、泄露国家秘密,不得侵犯国家社会集体的和公民的合法权益,不得利用本站制作、复制和传播不法有害信息!
二、互相尊重,对自己的言论和行为负责。
本文标题:
本页链接:比特客户端
您的位置:
详解大数据
详解大数据
详解大数据
详解大数据
开源C语言函数库Boost内存池使用与测试
关键字:C语言
  Boost库是一个可移植的开源C++函数库,鉴于STL(标准模板库)已经成为C++语言的一个组成部分,可以毫不夸张的说,Boost是目前影响最大的通用C++库。Boost库由C++标准委员会库工作组成员发起,其中有些内容有望成为下一代C++标准库内容,是一个“准”标准库。
  Boost内存池,即boost.pool库,是由Boost提供的一个用于内存池管理的开源C++库。作为Boost中影响较大的一个库,Pool已经被广泛使用。
  1. 什么是内存池“池”是在计算机技术中经常使用的一种设计模式,其在于:将程序中需要经常使用的核心资源先申请出来,放到一个池内,由程序自己管理,这样可以提高资源的使用效率,也可以保证本程序占有的资源数量。经常使用的池技术包括内存池、线程池和连接池等,其中尤以内存池和线程池使用最多。
  内存池(Memory Pool)是一种动态内存分配与管理技术。通常情况下,程序员习惯直接使用new、delete、malloc、free等API申请分配和释放内存,导致的后果时:当程序长时间运行时,由于所申请内存块的大小不定,频繁使用时会造成大量的内存碎片从而降低程序和的性能。内存池则是在真正使用内存之前,先申请分配一大块内存(内存池)留作备用,当程序员申请内存时,从池中取出一块动态分配,当程序员释放内存时,将释放的内存再放入池内,并尽量与周边的空闲内存块合并。若内存池不够时,则自动扩大内存池,从操作系统中申请更大的内存池。
  内存池的应用场景早期的内存池技术是为了专门解决那种频繁申请和释放相同大小内存块的程序,因此早期的一些内存池都是用相同大小的内存块链表组织起来的。
  Boost的内存池则对内存块的大小是否相同没有限制,因此只要是频繁动态申请释放内存的长时间运行程序,Boost内存池。这样可以有效减少内存碎片并提高程序运行效率。
  安装Boost的pool库是以C++头文件的形式提供的,不需要安装,也没有lib或者dll文件,仅仅需要将头文件包含到你的C++工程中就可以了。Boost的最新版本可以到http://www.boost.org/下载。
  2. 内存池的特征2.1 无内存泄露正确的使用内存池的申请和释放函数不会造成内存泄露,更重要的是,即使不正确的使用了申请和释放函数,内存池中的内存也会在进程结束时被全部自动释放,不会造成系统的内存泄露。
  2.2 申请的内存数组没有被填充例如一个元素的内存大小为A,那么元素数组若包含n个元素,则该数组的内存大小必然是A*n,不会有多余的内存来填充该数组。尽管每个元素也许包含一些填充的东西。
  2.3 任何数组内存块的位置都和使用operator new[]分配的内存块位置一致这表明你仍可以使用那些通过数组指针计算内存块位置的算法。
  2.4 内存池要比直接使用系统的动态内存分配快这个快是概率意义上的,不是每个时刻,每种内存池都比直接使用new或者malloc快。例如,当程序使用内存池时内存池恰好处于已经满了的状态,那么这次内存申请会导致内存池自我扩充,肯定比直接new一块内存要慢。但在大部分时候,内存池要比new或者malloc快很多。
  3. 内存池效率测试3.1 测试1:连续申请和连续释放分别用内存池和new连续申请和连续释放大量的内存块,比较其运行速度,代码如下:#include "stdafx.h" #include #include #include #include #include u
  const int MAXLENGTH = 100000;
  int main ( )
  { boost::pool&& p(sizeof(int));int* vec1[MAXLENGTH];int* vec2[MAXLENGTH];
  clock_t clock_begin = clock();for (int i = 0; i & MAXLENGTH; ++i)
  { vec1[i] = static_cast(p.malloc());} for (int i = 0; i & MAXLENGTH; ++i)
  { p.free(vec1[i]);vec1[i] = NULL;}
  clock_t clock_end = clock();cout&&"程序运行了 "&<CLOCK_END-CLOCK_BEGIN<<" p 个系统时钟?<<
  clock_begin = clock();for (int i = 0; i & MAXLENGTH; ++i)
  { vec2[i] =} for (int i = 0; i & MAXLENGTH; ++i)
  { delete vec2[i];vec2[i] = NULL;}
  clock_end = clock();cout&&"程序运行了 "&<CLOCK_END-CLOCK_BEGIN<<" p 个系统时钟?<<
  return 0;}测试环境:VS2008,WindowXP SP2,Pentium 4 CPU双核,1.5GB内存。
  结论:在连续申请和连续释放10万块内存的情况下,使用内存池耗时是使用new耗时的47.46%.
  3. 内存池效率测试3.1 测试1:连续申请和连续释放分别用内存池和new连续申请和连续释放大量的内存块,比较其运行速度,代码如下:#include "stdafx.h" #include #include #include #include #include u
  const int MAXLENGTH = 100000;
  int main ( )
  { boost::pool&& p(sizeof(int));int* vec1[MAXLENGTH];int* vec2[MAXLENGTH];
  clock_t clock_begin = clock();for (int i = 0; i & MAXLENGTH; ++i)
  { vec1[i] = static_cast(p.malloc());} for (int i = 0; i & MAXLENGTH; ++i)
  { p.free(vec1[i]);vec1[i] = NULL;}
  clock_t clock_end = clock();cout&&"程序运行了 "&<CLOCK_END-CLOCK_BEGIN<<" p 个系统时钟?<<
  clock_begin = clock();for (int i = 0; i & MAXLENGTH; ++i)
  { vec2[i] =} for (int i = 0; i & MAXLENGTH; ++i)
  { delete vec2[i];vec2[i] = NULL;}
  clock_end = clock();cout&&"程序运行了 "&<CLOCK_END-CLOCK_BEGIN<<" p 个系统时钟?<<
  return 0;}测试环境:VS2008,WindowXP SP2,Pentium 4 CPU双核,1.5GB内存。
  结论:在连续申请和连续释放10万块内存3.2 测试2:反复申请和释放小块内存代码如下:#include "stdafx.h" #include #include #include #include #include u
  const int MAXLENGTH = 500000;
  int main ( )
  { boost::pool&& p(sizeof(int));
  clock_t clock_begin = clock();for (int i = 0; i & MAXLENGTH; ++i)
  { int * t = static_cast(p.malloc());p.free(t);} clock_t clock_end = clock();cout&&"程序运行了 "&<CLOCK_END-CLOCK_BEGIN<<" p 个系统时钟?<<
  clock_begin = clock();for (int i = 0; i & MAXLENGTH; ++i)
  { int* t =} clock_end = clock();cout&&"程序运行了 "&<CLOCK_END-CLOCK_BEGIN<<" p 个系统时钟?<<
  return 0;}测试结果如下:
  结论:在反复申请和释放50万次内存的情况下,使用内存池耗时是使用new耗时的64.34%.的情况下,使用内存池耗时是使用new耗时的47.46%.
  3.3 测试3:反复申请和释放C++对象C++对象在动态申请和释放时,不仅要进行内存操作,同时还要调用构造和析购函数。因此有必要对C++对象也进行内存池的测试。
  代码如下:#include "stdafx.h" #include #include #include #include #include u
  const int MAXLENGTH = 500000;class A { public:A()
  { m_i++;} ~A( )
  { m_i――;} private:int m_i;};
  int main ( )
  { object_pool
  clock_t clock_begin = clock();for (int i = 0; i & MAXLENGTH; ++i)
  { A* a = q.construct();q.destroy(a);}
  clock_t clock_end = clock();cout&&"程序运行了 "&<CLOCK_END-CLOCK_BEGIN<<" p 个系统时钟?<<
  clock_begin = clock();for (int i = 0; i & MAXLENGTH; ++i)
  { A* a = new A;} clock_end = clock();cout&&"程序运行了 "&<CLOCK_END-CLOCK_BEGIN<<" p 个系统时钟?<<
  return 0;}测试结果如下:
  结论:在反复申请和释放50万个C++对象的情况下,使用内存池耗时是使用new耗时的112.03%.这是因为内存池的construct和destroy函数增加了函数调用次数的原因。这种情况下使用内存池并不能获得性能上的优化。
  4. Boost内存池的分类Boost内存池按照不同的理念分为四类。主要是两种理念的不同造成了这样的分类。
  一是Object Usage和Singleton Usage的不同。Object Usage意味着每个内存池都是一个可以创建和销毁的对象,一旦内存池被销毁则其所分配的所有内存都会被释放。Singleton Usage意味着每个内存池都是一个被静态分配的对象,直至程序结束才会被销毁,这也意味着这样的内存池是多线程安全的。只有使用release_memory或者 purge_memory方法才能释放内存。
  二是内存溢出的处理方式。第一种方式是返回NULL代表内存池溢出了;第二种方式是抛出异常代表内存池溢出。
  根据以上的理念,boost的内存池分为四种。
  4.1 Pool Pool是一个Object Usage的内存池,溢出时返回NULL. 4.2 object_pool object_pool与pool类似,唯一的区别是当其分配的内存释放时,它会尝试调用该对象的析购函数。
  4.3 singleton_pool singleton_pool是一个Singleton Usage的内存池,溢出时返回NULL. 4.4 pool_alloc pool_alloc是一个Singleton Usage的内存池,溢出时抛出异常。
  5. 内存池溢出的原理与解决方法5.1 必然溢出的内存内存池简化了很多内存方面的操作,也避免了一些错误使用内存对程序造成的损害。但是,使用内存池时最需要注意的一点是要处理内存池溢出的情况。
  没有不溢出的内存,下面的代码:#include "stdafx.h" #include #include #include #include #include u
  int _tmain(int argc, _TCHAR* argv[])
  { clock_t clock_begin = clock();int iLength = 0;for (int i = 0; ;++i)
  { void* p = malloc();&
[ 责任编辑:之极 ]
去年,手机江湖里的竞争格局还是…
甲骨文的云战略已经完成第一阶段…
软件信息化周刊
比特软件信息化周刊提供以数据库、操作系统和管理软件为重点的全面软件信息化产业热点、应用方案推荐、实用技巧分享等。以最新的软件资讯,最新的软件技巧,最新的软件与服务业内动态来为IT用户找到软捷径。
商务办公周刊
比特商务周刊是一个及行业资讯、深度分析、企业导购等为一体的综合性周刊。其中,与中国计量科学研究院合力打造的比特实验室可以为商业用户提供最权威的采购指南。是企业用户不可缺少的智选周刊!
比特网络周刊向企业网管员以及网络技术和产品使用者提供关于网络产业动态、技术热点、组网、建网、网络管理、网络运维等最新技术和实用技巧,帮助网管答疑解惑,成为网管好帮手。
服务器周刊
比特服务器周刊作为比特网的重点频道之一,主要关注x86服务器,RISC架构服务器以及高性能计算机行业的产品及发展动态。通过最独到的编辑观点和业界动态分析,让您第一时间了解服务器行业的趋势。
比特存储周刊长期以来,为读者提供企业存储领域高质量的原创内容,及时、全面的资讯、技术、方案以及案例文章,力求成为业界领先的存储媒体。比特存储周刊始终致力于用户的企业信息化建设、存储业务、数据保护与容灾构建以及数据管理部署等方面服务。
比特安全周刊通过专业的信息安全内容建设,为企业级用户打造最具商业价值的信息沟通平台,并为安全厂商提供多层面、多维度的媒体宣传手段。与其他同类网站信息安全内容相比,比特安全周刊运作模式更加独立,对信息安全界的动态新闻更新更快。
新闻中心热点推荐
新闻中心以独特视角精选一周内最具影响力的行业重大事件或圈内精彩故事,为企业级用户打造重点突出,可读性强,商业价值高的信息共享平台;同时为互联网、IT业界及通信厂商提供一条精准快捷,渗透力强,覆盖面广的媒体传播途径。
云计算周刊
比特云计算周刊关注云计算产业热点技术应用与趋势发展,全方位报道云计算领域最新动态。为用户与企业架设起沟通交流平台。包括IaaS、PaaS、SaaS各种不同的服务类型以及相关的安全与管理内容介绍。
CIO俱乐部周刊
比特CIO俱乐部周刊以大量高端CIO沙龙或专题研讨会以及对明星CIO的深入采访为依托,汇聚中国500强CIO的集体智慧。旨为中国杰出的CIO提供一个良好的互融互通 、促进交流的平台,并持续提供丰富的资讯和服务,探讨信息化建设,推动中国信息化发展引领CIO未来职业发展。
IT专家新闻邮件长期以来,以定向、分众、整合的商业模式,为企业IT专业人士以及IT系统采购决策者提供高质量的原创内容,包括IT新闻、评论、专家答疑、技巧和白皮书。此外,IT专家网还为读者提供包括咨询、社区、论坛、线下会议、读者沙龙等多种服务。
X周刊是一份IT人的技术娱乐周刊,给用户实时传递I最新T资讯、IT段子、技术技巧、畅销书籍,同时用户还能参与我们推荐的互动游戏,给广大的IT技术人士忙碌工作之余带来轻松休闲一刻。
微信扫一扫
关注Chinabyte}

我要回帖

更多关于 c语言万年历源代码 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信