• <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)系 :: 聚合  :: 管理

            公告


            最新評(píng)論

             

            閑來(lái)無(wú)事對(duì)jabberd2服務(wù)器閱讀了下,每次讀C++代碼,都首先花費(fèi)一些額外的時(shí)間領(lǐng)會(huì)代碼作者的抽象世界概念堆砌當(dāng)中,C則不同,直入主題,心理上不會(huì)有任何負(fù)擔(dān),不用徒勞輾轉(zhuǎn)在不同的世界理解和哲思之中,又一次拜倒在C的簡(jiǎn)潔明了之下
            ^^廢話不多說(shuō)了開始我們的內(nèi)容:
            內(nèi)存池實(shí)現(xiàn)相當(dāng)?shù)暮?jiǎn)單,由兩個(gè)個(gè)主要部分組成 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í)體釋放時(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; //下一個(gè)單獨(dú)內(nèi)存分塊
            };

            //內(nèi)存池--基于內(nèi)存池實(shí)體。管理一個(gè)由內(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)建一個(gè)新的內(nèi)存池
            JABBERD2_API pool_t _pool_new_heap(int size, char *file, int line); //構(gòu)建一個(gè)指定初始內(nèi)存區(qū)塊大小的內(nèi)存池
            JABBERD2_API void *pmalloc(pool_t, int size);//封裝 malloc函數(shù),內(nèi)存從內(nèi)存池中進(jìn)行分配,自動(dòng)完成釋放
            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)建一個(gè)新的空內(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;
            }

            //釋放一個(gè)內(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)存池時(shí)
            {
            p
            ->cleanup = pf;
            p
            ->cleanup_tail = pf;
            return;
            }

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

            //創(chuàng)建一個(gè)內(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)建一個(gè)內(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

            //生成對(duì)應(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)存請(qǐng)求函數(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)存,或者申請(qǐng)的內(nèi)存過大時(shí),直接從進(jìn)程堆中申請(qǐng)內(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)存,重新申請(qǐng)一塊
            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;

            }

            //對(duì)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)體申請(qǐng)空白內(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 閱讀(1554) 評(píng)論(3)  編輯 收藏 引用 所屬分類: C++/C

            Feedback

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

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

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

            国产精品久久久久久久app| 久久亚洲精品人成综合网| 久久超碰97人人做人人爱| 久久久噜噜噜久久中文字幕色伊伊 | 亚洲国产精品无码久久久秋霞2| 99久久无码一区人妻| 久久久精品人妻一区二区三区蜜桃 | 97久久精品午夜一区二区| 久久综合综合久久综合| 久久亚洲精品人成综合网| 国产精品久久久久久吹潮| 97久久超碰国产精品旧版| 久久精品国产亚洲沈樵| 国产精自产拍久久久久久蜜| 99久久精品国产一区二区蜜芽| 91精品国产色综久久| 精品久久久久中文字| 亚洲国产香蕉人人爽成AV片久久| 中文字幕久久亚洲一区| 久久久久人妻精品一区二区三区| 精品国产91久久久久久久| 久久97久久97精品免视看秋霞| 亚洲国产成人精品91久久久| 国内精品久久久久影院薰衣草 | 日韩人妻无码精品久久久不卡| 亚洲精品乱码久久久久久中文字幕 | 中文字幕成人精品久久不卡| 久久精品国产精品亚洲下载| 人妻无码αv中文字幕久久琪琪布| 久久久久高潮毛片免费全部播放| 国产成人精品久久亚洲高清不卡 国产成人精品久久亚洲高清不卡 国产成人精品久久亚洲 | 77777亚洲午夜久久多人| 69SEX久久精品国产麻豆| 国产精品无码久久综合网| 精品国产日韩久久亚洲| 久久婷婷国产麻豆91天堂| 久久精品免费一区二区| 久久久久国产精品| 人妻精品久久无码专区精东影业| 久久久久久一区国产精品| 97久久超碰成人精品网站|