zoukankan      html  css  js  c++  java
  • 内存池设计(四)

       memorypool 的设计  相比于 memoryblock 的设计就相对简单一点 主要是对其域初始化 其代码如下

       

    memorypool(int _ngrowsize=10,int _ninitsize=3)
    {
        cout<<"-----------------调用内存池的构造函数---------------"<<endl;
        ninitsize=_ninitsize;  // 首块长度
        ngrowsize=_ngrowsize;   //后续块长度
        pblock=NULL; // 链表指针置为 null
        nunitsize=sizeof(T);  // 定义存储单位大小
        if(sizeof(T)>4)///调整存储单位的大小
            nunitsize=(sizeof(T)+(MEMPOOL_ALIGNMENT-1)) & ~(MEMPOOL_ALIGNMENT-1);// 返回值为8的倍数 所谓的内存对齐
        else if(sizeof(T)<2)
            nunitsize=2;
        else
            nunitsize=4;
    }

       memorypool 的析构函数如下

       

    ~memorypool()
    {
        memoryblock<T>*pmyblock=pblock;
        while(pmyblock!=NULL)
        {
            pmyblock=pmyblock->pnext;
            delete(pmyblock);
        }
        cout<<"--------------------调用内存池的析构函数-------------------"<<endl;
    }

       在 memorypool中 主要操作就是用于向内存池请求存储单位的函数 allocate() ,这也是内存池向用户提供的主要服务。从程序的执行任务看,该函数的工作就是遍历内存块,找到 nfree 大于0 ,即有空闲单位的内存块,并从其上分配存储单位。然后将内存块 memoryblock 表中域 nfree 减一,并修改空闲单位链表头指针 nfirst 的值。

       其代码如下

       

    void *allocate(size_t num)
    {
        for(int i=0;i<num;++i)
        {
        if(NULL==pblock)
        {
            ///创建首内存块
            pblock=(memoryblock<T>*)new (nunitsize,ninitsize)
            memoryblock<T>(nunitsize,ninitsize);
            return (void*)pblock->adata;///返回内存块中数据元素存储区指针
        }
        ///为内存寻找符合条件的内存块
        memoryblock<T>*pmyblock=pblock;
        while(pmyblock!=NULL&&0==pmyblock->nfree)
            pmyblock=pmyblock->pnext;
        if(pmyblock!=NULL)
        {
            cout<<"找到内存空间 first= "<<pmyblock->nfirst<<endl;
            ///找到后进行内存分配
            char *pfree=pmyblock->adata+pmyblock->nfirst*nunitsize;
            pmyblock->nfirst=*((unsigned short*)pfree);
            pmyblock->nfree--;
            ///返回找到的存储单位指针
            return (void*)pfree;
        }
        else
        {
            ///没有找到 说明当前内存块已用完
            if(0==ngrowsize)return NULL;
            cout<<" 否则分配新内存块"<<endl;
            //分配一个后续内存块
            pmyblock=(memoryblock<T>*)new(nunitsize,ngrowsize)
            memoryblock<T>(nunitsize,ngrowsize);
            if(NULL==pmyblock)
                return NULL;///失败
            pmyblock->pnext=pblock;
            pblock=pmyblock;
            //返回新内存的的存储区指针
            return (void*)pmyblock->adata;
        }
    }
    }

           memorypool 的另一个重要函数就是用于释放内存的 free() ,该函数根据 pfree 的值,找到他所在的内存块,然后将他的序号 nfirst 的值(因为他绝对空闲) ,在pfree 的头两个字节写入原来nfirst的值,然后判断 该 块的是否全为 free 方法是检测 nfree*nunitsize==nsize. 若是,则向系统释放内存,若不是,则将该 block放到链表的头部,因为该block上含有空闲的内存单元,这样可以减少分配时遍历链表所消耗的时间。

    void free(void *pfree)
    {
        //找到p所在的块
        cout<<"释放存储单位内存空间"<<endl;
        memoryblock<T>*pmyblock=pblock;
        memoryblock<T>*preblock=NULL;
        while(pmyblock!=NULL&&(pblock->adata>pfree||pmyblock->adata+pmyblock->nsize))
        {
            preblock=pmyblock;
            pmyblock=pmyblock->pnext;
        }
        //该内存块在被内存池pmyblock 所指向的内存块中
        if(NULL!=pmyblock)
        {
            //1 修改数组链表
            *((unsigned short*)pfree)=pmyblock->nfirst;
            pmyblock->nfirst=(unsigned short)((unsigned long)pfree-(unsigned long)pmyblock->adata)/nunitsize;
            pmyblock->nfree++;
            // 2 判断是否需要向系统释放内存
            if(pmyblock->nsize==pmyblock->nfree*nunitsize)
            {
                //在链表中删除
                delete(pmyblock);
            }
            else
            {
                //将该block 插入队首
                preblock=pmyblock->pnext;
                pmyblock->pnext=pblock;
                pblock=pmyblock;
            }
        }
    }

      

  • 相关阅读:
    flink 使用processFunction函数的sideOutPut实现filter操作(java版)
    flink 状态编程之RichFlatMapFunction用法-java
    java flink之eventTime和window
    java spark sql 计算各个省份广告点击数的top3
    java spark 计算各个省份广告点击数的top3
    java streaming转换算子window,countByWindow
    java spark转换算子sortByKey
    java spark转换算子join、leftOuterJoin、rightOuterJoin、fullOuterjoin
    java spark转换算子groupByKey、reduceByKey、aggregateByKey
    java spark转换算子union、intersection、subtract
  • 原文地址:https://www.cnblogs.com/guoyu1024/p/9607051.html
Copyright © 2011-2022 走看看