• <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>
            OldJiang.com

            浩毛的博客

            OldJiang.com
            posts - 14, comments - 81, trackbacks - 0, articles - 0
              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理
                 都知道頻繁分配內(nèi)存釋放內(nèi)存很耗系統(tǒng)資源,而且容易造成內(nèi)存碎片。因此寫了個簡單的內(nèi)存池實現(xiàn),越簡單越好,為什么?做復(fù)雜了效率還不如直接malloc。因此這個內(nèi)存池采用鏈表連接內(nèi)存塊的方式,分配的是固定大小的內(nèi)存塊,從池中取內(nèi)存和歸還內(nèi)存是用的空閑鏈表堆棧操作, 沒有使用線程鎖,如果要線程安全,建議在外部調(diào)用內(nèi)存池的地方加鎖。

                 做過一個簡單的測試,10萬次內(nèi)存池調(diào)用的效率大概比直接分配釋放內(nèi)存提高了30-50%。但是前提是內(nèi)存池不能加鎖(pthread_mutex),加鎖的內(nèi)存池效率和直接分配內(nèi)存的效率差不多,有時候還要多點點。(測試的環(huán)境是每次2K,4個雙核CPU,F(xiàn)REEBSD7)

            代碼實現(xiàn):
            struct memblock
            {
               
            int              used;
               
            void*            data;
               
            struct memblock* next;
               
            struct memblock* createnext;
            }
            ;


            struct mempool
            {
                
            int            size;//memblock大小
                int            unused;//空閑的memblock大小
                int            datasize;//每次分配的數(shù)據(jù)大小(就是memblock.data)
                struct memblock*    free_linkhead;//空閑memblock鏈表頭
                struct memblock*    create_linkhead;//所有創(chuàng)建的memblock鏈表頭,內(nèi)存池釋放的時候使用,防止內(nèi)存池釋放的似乎還有memblock未歸還的情況
                
            };
            typedef 
            void (*free_callback)(void*);//釋放回調(diào)函數(shù),釋放membloc.data用,可以簡單的直接用free函數(shù)

            void    mempool_init(int initialSize,int datasize);//初始化mempool
            void    mempool_dealloc(struct mempool* pool,free_callback callback);//釋放mempool
            void*    mempool_get(struct mempool* pool);//獲取一個memblock
            void    mempool_release(struct mempool* pool,struct memblock* block);//歸還一個memblock

            /*********************************
             * mempool
             * *****************************
            */
            //malloc一個memblock
            static struct memblock* mempool_allocblock( struct mempool* pool );

            //------------------implement--------
            void*
            mempool_init( 
            int initialSize, int datasize )
            {
                
            struct mempool* pool = malloc( sizeofstruct mempool ) );
                pool
            ->unused = 0;
                pool
            ->datasize = datasize;
                pool
            ->free_linkhead = NULL;
              
                
            //預(yù)先初始化initialSize個內(nèi)存塊
                 pool->create_linkhead = NULL;
                
            int i;
                
            for ( i = 0; i < initialSize; i++ ) {
                    
            struct memblock* block = mempool_allocblock( pool );
                    mempool_release( pool, block );
                }
                
            return ( pool );
            }

            void
            mempool_dealloc( 
            struct mempool* pool, free_callback callback )
            {
                
            struct memblock* block = NULL;
                
            //將所有創(chuàng)建的memblock釋放了
                while ( pool->create_linkhead != NULL ) {
                    block 
            = pool->create_linkhead;
                    pool
            ->create_linkhead = pool->create_linkhead->createnext;
                
            //執(zhí)行free回調(diào)。
                    if ( callback ) {
                        ( 
            *callback )( block->data );
                    }
                    free( block );
                }
                free( pool );
                L_DEBUG( 
            "%s:size(%d),unused(%d)", __func__, pool->size, pool->unused );
            }

            static struct memblock*
            mempool_allocblock( 
            struct mempool* pool )
            {
                
            struct memblock* block = malloc( sizeofstruct memblock ) );
                block
            ->data = malloc( sizeof( pool->datasize ) );
                block
            ->next = NULL;
                block
            ->used = 1;//表示已使用

                
            //加入所有創(chuàng)建的memblock的鏈表頭
                block->createnext = pool->create_linkhead;
                pool
            ->create_linkhead = block;

                pool
            ->size++;
                
            return ( block );
            }

            void
            mempool_release( 
            struct mempool* pool, struct memblock* block )
            {
                
            if ( block == NULL ) {
                    L_WARN( 
            "%s:release a NULL!", __func__ );
                    
            return;
                }
                
            if ( block->used != 1 ) {
                    L_WARN( 
            "%s:used!=1", __func__ );
                    
            return;
                }
                
            //將歸還的內(nèi)存塊放到空閑鏈表頭。
                block->used = 0;//表示空閑
                block->next = pool->free_linkhead;
                pool
            ->free_linkhead = block;
                pool
            ->unused++;//空閑數(shù)+1
            }

            void*
            mempool_get( 
            struct mempool* pool )
            {
               
                
            struct memblock* block = NULL;
                
            if ( pool->free_linkhead ) {
                
            //從空閑鏈表頭取出一個內(nèi)存塊
                    block = pool->free_linkhead;
                    pool
            ->free_linkhead = pool->free_linkhead->next;
                    block
            ->next = NULL;
                    block
            ->used = 1;//表示已使用
                    pool->unused--;//空閑內(nèi)存塊數(shù)-1
                }
                
            else {
                
            //沒有空閑的內(nèi)存塊,創(chuàng)建一個
                    block = mempool_allocblock( pool );
                }
                
            return ( block );
            }

            Feedback

            # re: 一個簡單實用的內(nèi)存池(c實現(xiàn))[未登錄]  回復(fù)  更多評論   

            2009-09-18 09:08 by kkk
            struct memblock*沒定義吧

            # re: 一個簡單實用的內(nèi)存池(c實現(xiàn))  回復(fù)  更多評論   

            2009-09-18 09:27 by 浩毛
            代碼第二行開始就是定義。。

            struct mempool
            {
            int size;//memblock大小
            int unused;//空閑的memblock大小
            int datasize;//每次分配的數(shù)據(jù)大小(就是memblock.data)
            struct memblock* free_linkhead;//空閑memblock鏈表頭
            struct memblock* create_linkhead;//所有創(chuàng)建的memblock鏈表頭,內(nèi)存池釋放的時候使用,防止內(nèi)存池釋放的似乎還有memblock未歸還的情況

            };

            # re: 一個簡單實用的內(nèi)存池(c實現(xiàn))  回復(fù)  更多評論   

            2009-09-18 09:30 by wangjinhu
            不加鎖的內(nèi)存池給誰用?

            # re: 一個簡單實用的內(nèi)存池(c實現(xiàn))  回復(fù)  更多評論   

            2009-09-18 09:33 by 浩毛
            如果要線程安全,建議在外部調(diào)用內(nèi)存池的地方加鎖。

            # re: 一個簡單實用的內(nèi)存池(c實現(xiàn))  回復(fù)  更多評論   

            2009-09-18 15:12 by 亂78糟
            @浩毛
            加鎖的內(nèi)存池效率和直接分配內(nèi)存的效率差不多,有時候還要多點點。

            這個這個。。。。

            # re: 一個簡單實用的內(nèi)存池(c實現(xiàn))  回復(fù)  更多評論   

            2009-09-18 15:35 by blocker
            struct memblock定義在哪?

            # re: 一個簡單實用的內(nèi)存池(c實現(xiàn))  回復(fù)  更多評論   

            2009-09-18 16:38 by feilng
            內(nèi)存是拿來用的,不是拿來供的
            對于服務(wù)器應(yīng)用來說,核心對象完全可以全部預(yù)先分配好,盡量減少臨時對象,剩余必須頻繁而臨時的對象就放在專門的臨時內(nèi)存區(qū)管理。
            分開對待好一點,不要指望一種內(nèi)存管理機制哪里都用。

            # re: 一個簡單實用的內(nèi)存池(c實現(xiàn))  回復(fù)  更多評論   

            2009-09-18 20:05 by 浩毛
            @亂78糟
            我是測試的10萬次2K內(nèi)存,環(huán)境是freebsd 4CPU的服務(wù)器

            @feilng
            我只是給出一個簡單的內(nèi)存池實現(xiàn),具體怎么用就見仁見智了。。
            另外,我作的網(wǎng)絡(luò)服務(wù)器是多進(jìn)程單線程的方式,對小塊內(nèi)存的頻繁分配的情況采用的這種內(nèi)存池管理的,也不需要加鎖。

            # re: 一個簡單實用的內(nèi)存池(c實現(xiàn))  回復(fù)  更多評論   

            2009-09-20 11:11 by 戴爾電腦
            深刻地方就開始點擊附件是的

            # re: 一個簡單實用的內(nèi)存池(c實現(xiàn))  回復(fù)  更多評論   

            2009-09-21 14:02 by hexin
            這個功能你去看看boost的Simple Segregated Storage,比你這個快多了,代碼也不比這個多

            # re: 一個簡單實用的內(nèi)存池(c實現(xiàn))  回復(fù)  更多評論   

            2009-09-22 11:18 by 陳梓瀚(vczh)
            我一直都是用一顆平衡樹來組織一堆固定大小的數(shù)組實現(xiàn)的池。

            # re: 一個簡單實用的內(nèi)存池(c實現(xiàn))  回復(fù)  更多評論   

            2009-09-22 17:51 by 浩毛
            @hexin
            第一,這個是c實現(xiàn)的。boost的是C++實現(xiàn)。
            第二,除了內(nèi)存池初始化和結(jié)束的時候是個循環(huán)malloc/free外,從池中取內(nèi)存和歸還內(nèi)存就是幾個簡單的指針操作(堆棧操作),沒有循環(huán)遍歷檢索。我覺得夠快了。

            另外這個只適合固定的內(nèi)存管理。下次打算做個不固定長度的內(nèi)存池。

            # re: 一個簡單實用的內(nèi)存池(c實現(xiàn))  回復(fù)  更多評論   

            2009-09-22 22:36 by hexin
            c實現(xiàn)和c++的實現(xiàn)在這里沒有區(qū)別,這里不會用到只有c++才有的特性

            對于一塊被頻繁調(diào)用的code來說影響速度的不僅有算法的復(fù)雜度,還要考量cache locality,后者肯定沒有boost做得好,前者也不會比boost好,你可以拿兩份代碼測試比較一下

            # re: 一個簡單實用的內(nèi)存池(c實現(xiàn))  回復(fù)  更多評論   

            2009-09-22 22:41 by hexin
            @浩毛
            不固定長度的內(nèi)存池,現(xiàn)有的高性能的實現(xiàn)就更多了,先吸收一下前人的經(jīng)驗吧

            # re: 一個簡單實用的內(nèi)存池(c實現(xiàn))  回復(fù)  更多評論   

            2009-09-26 14:56 by 浩毛
            @hexin
            我看了BOOST的Simple Segregated Storage,和我下一篇要寫的新的內(nèi)存池原理上差不多的。請關(guān)注下一篇文章。
            現(xiàn)在這個實現(xiàn)更像是一個后備列表(Lookaside Lists)的實現(xiàn)。從原理上來看,我并不認(rèn)為這個就比Simple Segregated Storage的方式慢了。

            # re: 一個簡單實用的內(nèi)存池(c實現(xiàn))  回復(fù)  更多評論   

            2009-09-26 14:58 by 浩毛
            @hexin
            不過現(xiàn)在這個內(nèi)存池,申請釋放內(nèi)存都必須是struct memblock結(jié)構(gòu),使用上來說沒有直接malloc得到一個地址指針那種方便。下篇文章將解決這個問題。

            # re: 一個簡單實用的內(nèi)存池之一(c實現(xiàn))  回復(fù)  更多評論   

            2009-09-26 15:03 by 浩毛
            @kkk
            memblock加上了,排版的原因。。

            # re: 一個簡單實用的內(nèi)存池之一(c實現(xiàn))  回復(fù)  更多評論   

            2010-08-30 15:47 by vivian1683
            http://blog.sina.com.cn/s/articlelist_1791090757_10_1.html

            我是獵頭vivian..大量職位IT在招聘中.如果有考慮的朋友請發(fā)簡歷到vivian1683@live.cn
            OldJiang.com
            99久久伊人精品综合观看| 人妻精品久久无码专区精东影业| 久久精品国产第一区二区三区| 日产精品久久久久久久| 国产情侣久久久久aⅴ免费| 麻豆成人久久精品二区三区免费 | 久久激情五月丁香伊人| 亚洲日本久久久午夜精品| 久久久久久久人妻无码中文字幕爆| 伊人丁香狠狠色综合久久| 大香伊人久久精品一区二区 | 亚洲欧美一级久久精品| 青青草原精品99久久精品66| 久久美女人爽女人爽| 99久久这里只精品国产免费| 99久久99久久精品免费看蜜桃| 人妻系列无码专区久久五月天| 无码AV波多野结衣久久| 久久婷婷五月综合97色直播| 亚洲AV无码一区东京热久久 | 中文字幕无码免费久久| 久久久久亚洲爆乳少妇无| 国产精品久久久久久久久| 久久精品国产乱子伦| 亚洲欧美国产精品专区久久| 国产精品午夜久久| 久久精品国产91久久麻豆自制| 无码伊人66久久大杳蕉网站谷歌| 日日狠狠久久偷偷色综合0 | 奇米综合四色77777久久| 亚洲伊人久久成综合人影院 | 色播久久人人爽人人爽人人片aV | 无码人妻久久一区二区三区蜜桃| 国产成人精品久久一区二区三区av| 97精品伊人久久久大香线蕉| 漂亮人妻被中出中文字幕久久| 亚洲国产成人精品久久久国产成人一区二区三区综 | 久久免费看黄a级毛片| 久久久久久国产a免费观看黄色大片| 欧美一级久久久久久久大片| 香港aa三级久久三级老师2021国产三级精品三级在 |