• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            大城小魔

            天下難事,必作于易;天下大事,必作于細(xì)

              C++博客 ::  :: 聯(lián)系 :: 聚合  :: 管理

            公告


            最新評論

             

            閑來無事對jabberd2服務(wù)器閱讀了下,每次讀C++代碼,都首先花費(fèi)一些額外的時間領(lǐng)會代碼作者的抽象世界概念堆砌當(dāng)中,C則不同,直入主題,心理上不會有任何負(fù)擔(dān),不用徒勞輾轉(zhuǎn)在不同的世界理解和哲思之中,又一次拜倒在C的簡潔明了之下
            ^^廢話不多說了開始我們的內(nèi)容:
            內(nèi)存池實(shí)現(xiàn)相當(dāng)?shù)暮唵危蓛蓚€個主要部分組成 pheap,pfree,pool_struct,以及基本的內(nèi)存池API

            pheap:         內(nèi)存塊,它由pfree組織管理
            pfree:          由pheap構(gòu)成鏈表,它作為內(nèi)存池實(shí)體單元
            pool_struct: 內(nèi)存池結(jié)構(gòu)體
             

            //pool.h文件
            //=========================================================================
            //于內(nèi)存池中的實(shí)體(內(nèi)存塊)關(guān)聯(lián)的回調(diào)函數(shù),當(dāng)實(shí)體釋放時調(diào)用
            typedef void (*pool_cleanup_t)(void *arg);
            //單獨(dú)內(nèi)存分塊
            struct pheap
            {
            void *block; //實(shí)際的數(shù)據(jù)內(nèi)存塊
            int size,used; //實(shí)際大小,使用大小
            };
            //帶有釋放內(nèi)存毀掉函數(shù)的內(nèi)存分塊鏈表結(jié)點(diǎn)(內(nèi)存池實(shí)體)
            struct pfree

            pool_cleanup_t f; 
            //內(nèi)存釋放毀掉函數(shù)
            void *arg; 
            struct pheap *heap; //單獨(dú)內(nèi)存分塊
            struct pfree *next; //下一個單獨(dú)內(nèi)存分塊
            };

            //內(nèi)存池--基于內(nèi)存池實(shí)體。管理一個由內(nèi)存池實(shí)體(pfree)組成的鏈表。
            typedef struct pool_struct
            {
            int size; //內(nèi)存池大小
            struct pfree *cleanup; //鏈表首結(jié)點(diǎn)
            struct pfree *cleanup_tail; //鏈表尾結(jié)點(diǎn)
            struct pheap *heap; 
            #ifdef POOL_DEBUG 
            //調(diào)試信息
            char name[8], zone[32];
            int lsize;
            #endif
            } _pool, 
            *pool_t;

            #ifdef POOL_DEBUG 
            //調(diào)式調(diào)用函數(shù)版本定義宏
            # define pool_new() _pool_new(__FILE__,__LINE__) 
            # define pool_heap(i) _pool_new_heap(i,__FILE__,__LINE__) 
            #else
            # define pool_heap(i) _pool_new_heap(i,NULL,
            0
            # define pool_new() _pool_new(NULL,
            0)
            #endif

            //jabberd2內(nèi)存池API函數(shù)定義
            JABBERD2_API pool_t _pool_new(char *file, int line); //構(gòu)建一個新的內(nèi)存池
            JABBERD2_API pool_t _pool_new_heap(int size, char *file, int line); //構(gòu)建一個指定初始內(nèi)存區(qū)塊大小的內(nèi)存池
            JABBERD2_API void *pmalloc(pool_t, int size);//封裝 malloc函數(shù),內(nèi)存從內(nèi)存池中進(jìn)行分配,自動完成釋放
            JABBERD2_API void *pmalloc_x(pool_t p, int size, char c); /* Wrapper around pmalloc which prefils buffer with c */
            JABBERD2_API 
            void *pmalloco(pool_t p, int size); /* YAPW for zeroing the block */
            JABBERD2_API 
            char *pstrdup(pool_t p, const char *src); /* wrapper around strdup, gains mem from pool */
            JABBERD2_API 
            char *pstrdupx(pool_t p, const char *src, int len); /* use given len */
            JABBERD2_API 
            void pool_stat(int full); /* print to stderr the changed pools and reset */
            JABBERD2_API 
            void pool_cleanup(pool_t p, pool_cleanup_t fn, void *arg); /* calls f(arg) before the pool is freed during cleanup */
            JABBERD2_API 
            void pool_free(pool_t p);//調(diào)用所有的內(nèi)存釋放回調(diào)函數(shù),釋放所有內(nèi)存池中的數(shù)據(jù),刪除內(nèi)存池本身
            JABBERD2_API int pool_size(pool_t p); //返回內(nèi)存中已分配的總字節(jié)數(shù)

             

            //pool.c文件
            //=========================================================================

            //構(gòu)建一個新的空內(nèi)存池
            pool_t _pool_new(char *zone, int line)
            {
            pool_t p; 
            while((p = _pool__malloc(sizeof(_pool))) == NULL) sleep(1);
            p
            ->cleanup = NULL; //初始空鏈表
            p->heap = NULL; //同上
            p->size = 0

            #ifdef POOL_DEBUG
            p
            ->lsize = -1;
            p
            ->zone[0= '\0';
            snprintf(p
            ->zone, sizeof(p->zone), "%s:%i", zone, line);
            sprintf(p
            ->name,"%X",(int)p);

            if(pool__disturbed == NULL)
            {
            pool__disturbed 
            = (xht)1/* reentrancy flag! */
            pool__disturbed 
            = xhash_new(POOL_NUM);
            }
            if(pool__disturbed != (xht)1)
            xhash_put(pool__disturbed,p
            ->name,p);
            #endif

            return p;
            }

            //釋放一個內(nèi)存分塊
            static void _pool_heap_free(void *arg)
            {
            struct pheap *= (struct pheap *)arg;

            _pool__free(h
            ->block); //free數(shù)據(jù)內(nèi)存塊
            _pool__free(h); //free pheap結(jié)構(gòu)體自身
            }

            //向內(nèi)存池中添加內(nèi)存池實(shí)體pfree
            static void _pool_cleanup_append(pool_t p, struct pfree *pf)
            {
            struct pfree *cur;

            if(p->cleanup == NULL)//空內(nèi)存池時
            {
            p
            ->cleanup = pf;
            p
            ->cleanup_tail = pf;
            return;
            }

            //鏈表末尾添加新實(shí)體
            cur = p->cleanup_tail; 
            cur
            ->next = pf;
            p
            ->cleanup_tail = pf;
            }

            //創(chuàng)建一個內(nèi)存池實(shí)體
            static struct pfree *_pool_free(pool_t p, pool_cleanup_t f, void *arg)
            {
            struct pfree *ret;

            //為內(nèi)存池實(shí)體分配內(nèi)存
            while((ret = _pool__malloc(sizeof(struct pfree))) == NULL) sleep(1);
            ret
            ->= f; //內(nèi)存塊釋放回調(diào)函數(shù)
            ret->arg = arg; //回調(diào)函數(shù)參數(shù)
            ret->next = NULL;

            return ret;
            }
            //創(chuàng)建一個內(nèi)存塊,并為其設(shè)置內(nèi)存釋放回調(diào)函數(shù)
            static struct pheap *_pool_heap(pool_t p, int size)
            {
            struct pheap *ret; //數(shù)據(jù)內(nèi)存塊結(jié)構(gòu)體
            struct pfree *clean; //內(nèi)存池實(shí)體

            //分配內(nèi)存數(shù)據(jù)塊結(jié)構(gòu)體內(nèi)存
            while((ret = _pool__malloc(sizeof(struct pheap))) == NULL) sleep(1); 
            //分配數(shù)據(jù)內(nèi)存塊內(nèi)存
            while((ret->block = _pool__malloc(size)) == NULL) sleep(1);
            ret
            ->size = size; //指定數(shù)據(jù)內(nèi)存塊大小
            p->size += size; //更新內(nèi)存池總字節(jié)數(shù)
            ret->used = 0

            //生成對應(yīng)的內(nèi)存池實(shí)體,_pool_heap_free為靜態(tài)函數(shù)地址,ret為其調(diào)用參數(shù)
            clean = _pool_free(p, _pool_heap_free, (void *)ret);
            clean
            ->heap = ret; /* for future use in finding used mem for pstrdup */
            _pool_cleanup_append(p, clean);
            //將內(nèi)存池實(shí)體,添加到內(nèi)存池實(shí)體鏈表中

            return ret;
            }

            //內(nèi)存池內(nèi)存請求函數(shù)
            void *pmalloc(pool_t p, int size)
            {
            void *block;

            if(p == NULL)
            {
            fprintf(stderr,
            "Memory Leak! [pmalloc received NULL pool, unable to track allocation, exiting]\n");
            abort();
            }

            //如果內(nèi)存池中沒有可用內(nèi)存,或者申請的內(nèi)存過大時,直接從進(jìn)程堆中申請內(nèi)存
            if(p->heap == NULL || size > (p->heap->size / 2))

            while((block = _pool__malloc(size)) == NULL) sleep(1); //直接從進(jìn)程內(nèi)存堆上分配
            p->size += size; //遞增內(nèi)存池總字節(jié)數(shù)
            _pool_cleanup_append(p, _pool_free(p, _pool__free, block));//生成相應(yīng)的內(nèi)存池實(shí)體,并添加到內(nèi)存池實(shí)體鏈表中
            return block;
            }

            /* we have to preserve boundaries, long story :) */
            if(size >= 4)
            while(p->heap->used&7) p->heap->used++;

            /* if we don't fit in the old heap, replace it */
            // 如果在現(xiàn)有內(nèi)存塊中沒有足夠的內(nèi)存,重新申請一塊
            if(size > (p->heap->size - p->heap->used))
            p
            ->heap = _pool_heap(p, p->heap->size);

            //當(dāng)前內(nèi)存塊有剩余空間
            block = (char *)p->heap->block + p->heap->used; //返回內(nèi)存區(qū)塊有效地址
            p->heap->used += size; //更新內(nèi)存區(qū)塊使用情況
            return block;

            }

            //對pmalloc進(jìn)行封裝并使用參數(shù)c的內(nèi)容預(yù)填充新內(nèi)存塊
            void *pmalloc_x(pool_t p, int size, char c)
            {
            void* result = pmalloc(p, size);
            if (result != NULL)
            memset(result, c, size);
            return result;



            //方便,安全(為結(jié)構(gòu)體申請空白內(nèi)存等)
            void *pmalloco(pool_t p, int size)
            {
            void *block = pmalloc(p, size);
            memset(block, 
            0, size);
            return block;
            }


             

             

             

             

            posted on 2008-11-13 23:40 momor 閱讀(1545) 評論(3)  編輯 收藏 引用 所屬分類: C++/C

            Feedback

            # re: jabberd2的內(nèi)存池 2008-11-14 10:45 zuhd
            這個池能否實(shí)現(xiàn)分配不等大小的內(nèi)存,能否對碎片進(jìn)行整理?否則和boost沒有什么區(qū)別  回復(fù)  更多評論
              

            # re: jabberd2的內(nèi)存池 2008-11-14 11:04 momor
            老實(shí)說,本人也認(rèn)為這個內(nèi)存池還是很弱,它主要針對保證對內(nèi)存泄露的控制,預(yù)先分配的大內(nèi)存塊,也可以保證內(nèi)存碎片的產(chǎn)生,一定程度提高了內(nèi)存塊分配的速度,它可以實(shí)現(xiàn)不等大小內(nèi)存的分配。
            我個人還是傾向SGI內(nèi)存池的實(shí)現(xiàn),它根據(jù)所需分配的不同內(nèi)存大小的索引表進(jìn)行空閑內(nèi)存鏈表的管理。邏輯上和功能實(shí)現(xiàn)上都比較清晰  回復(fù)  更多評論
              

            # re: jabberd2的內(nèi)存池 2008-11-19 13:29 xto
            這種內(nèi)存池可能主要用于效率和性能比較高的地方,例如通信服務(wù)端接受數(shù)據(jù)時用以裝載數(shù)據(jù)的內(nèi)存區(qū)域。如果頻繁的新建和釋放內(nèi)存,必然可能會產(chǎn)生內(nèi)存碎片,更常見的則是cpu在創(chuàng)建和釋放內(nèi)存時性能的損耗。因此才會創(chuàng)建內(nèi)存池對數(shù)據(jù)進(jìn)行處理。其實(shí)很多通信服務(wù)端常用的線程池,內(nèi)存池都有這個原理在里面  回復(fù)  更多評論
              

            久久无码中文字幕东京热| 日韩久久久久中文字幕人妻| 亚洲国产综合久久天堂 | 97精品国产97久久久久久免费| 欧美精品一区二区精品久久| 精品久久久久香蕉网| 少妇久久久久久久久久| 无码AV波多野结衣久久| 亚洲精品乱码久久久久久久久久久久 | 91精品国产91久久久久久蜜臀| 久久99国产精品99久久| 久久99国产精品久久久 | 国产免费福利体检区久久| 曰曰摸天天摸人人看久久久| 国产精自产拍久久久久久蜜| 91精品国产91热久久久久福利| 国内精品伊人久久久久影院对白| 久久久久国产| 久久久久久久久久久久久久| 久久国产精品无码HDAV| 久久伊人精品青青草原高清| 久久久无码精品午夜| 久久妇女高潮几次MBA| 久久综合狠狠综合久久| 国产精品午夜久久| 久久人人爽人人爽人人片AV麻烦 | 亚洲国产日韩欧美久久| 亚洲乱码精品久久久久..| 亚洲国产精品热久久| 一本一本久久a久久精品综合麻豆| 一本一本久久A久久综合精品| 国产精品久久久久久福利69堂| 久久久久久国产精品美女| 久久久久亚洲AV成人片| 久久久精品人妻无码专区不卡| 色婷婷综合久久久久中文一区二区 | 亚洲国产日韩综合久久精品| 久久精品人人做人人爽电影蜜月| 久久久精品日本一区二区三区| 久久精品国产网红主播| 久久无码精品一区二区三区|