亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

GlusterFS之內(nèi)存池(mem-pool)使用實(shí)例分析

系統(tǒng) 1955 0

我的新浪微博: http://weibo.com/freshairbrucewoo

歡迎大家相互交流,共同提高技術(shù)。

?

上一篇博客詳細(xì)分析了GlusterFS之內(nèi)存池的實(shí)現(xiàn)技術(shù),今天我們看看GlusterFS是怎么使用這個技術(shù)的。

第一步:分配和初始化:

cli進(jìn)程在初始化的過程中會涉及到內(nèi)存池的建立和初始化,具體涉及到內(nèi)存池初始化的代碼如下(在cli.c文件中的glusterfs_ctx_defaults_init函數(shù)):

      
         1
      
      
        /*
      
      
         frame_mem_pool size 112 * 64 
      
      
        */
      
      
         2
      
       pool->frame_mem_pool = mem_pool_new (call_frame_t, 
      
        32
      
      );
      
        //
      
      
        為調(diào)用針對象分配內(nèi)存池對象,對象類型是call_frame_t,32個這樣的內(nèi)存塊  
      
      
         3
      
      
        if
      
       (!pool->
      
        frame_mem_pool)  


      
      
         4
      
      
        return
      
       -
      
        1
      
      
        ;  


      
      
         5
      
      
         6
      
      
        /*
      
      
         stack_mem_pool size 256 * 128 
      
      
        */
      
      
         7
      
       pool->stack_mem_pool = mem_pool_new (call_stack_t, 
      
        16
      
      );
      
        //
      
      
        為調(diào)用堆棧對象分配內(nèi)存池對象,對象類型是call_stack_t,16個這樣的內(nèi)存塊  
      
      
         8
      
      
         9
      
      
        if
      
       (!pool->
      
        stack_mem_pool)  


      
      
        10
      
      
        return
      
       -
      
        1
      
      
        ;  


      
      
        11
      
      
        12
      
       ctx->stub_mem_pool = mem_pool_new (call_stub_t, 
      
        16
      
      
        );  


      
      
        13
      
      
        if
      
       (!ctx->
      
        stub_mem_pool)  


      
      
        14
      
      
        return
      
       -
      
        1
      
      
        ;  


      
      
        15
      
      
        16
      
       ctx->dict_pool = mem_pool_new (dict_t, 
      
        32
      
      
        );  


      
      
        17
      
      
        if
      
       (!ctx->
      
        dict_pool)  


      
      
        18
      
      
        return
      
       -
      
        1
      
      
        ;  


      
      
        19
      
      
        20
      
       ctx->dict_pair_pool = mem_pool_new (data_pair_t, 
      
        512
      
      
        );  


      
      
        21
      
      
        if
      
       (!ctx->
      
        dict_pair_pool)  


      
      
        22
      
      
        return
      
       -
      
        1
      
      
        ;  


      
      
        23
      
      
        24
      
       ctx->dict_data_pool = mem_pool_new (data_t, 
      
        512
      
      
        );  


      
      
        25
      
      
        if
      
       (!ctx->
      
        dict_data_pool)  


      
      
        26
      
      
        return
      
       -
      
        1
      
      ;  
    

?

由上面的代碼可以看出:集合系統(tǒng)中各種結(jié)構(gòu)體對象可能實(shí)際會用到的數(shù)量來預(yù)先分配好,真正需要為對象內(nèi)存的時候直接從這些內(nèi)存池中取就可以了,用完之后又放回內(nèi)存池,這樣減少了分配和釋放內(nèi)存的額外系統(tǒng)開銷,分配內(nèi)存往往需要從用戶態(tài)到內(nèi)核態(tài)切換,這些都是很耗時間的,當(dāng)然相同的對象還減少了初始化的時間。

?

代碼分配內(nèi)存調(diào)用的函數(shù)是mem_pool_new,而不是在上一篇博客結(jié)束的mem_pool_new_fn函數(shù),那是因?yàn)閙em_pool_new是定義的宏函數(shù),就是調(diào)用mem_pool_new_fn函數(shù),函數(shù)參數(shù)分別表示對象所占內(nèi)存大小、數(shù)量和名稱(為分配的內(nèi)存起一個名字,就是對象的名稱);

?

      
        1
      
      
        #define
      
       mem_pool_new(type,count) mem_pool_new_fn (sizeof(type), count, #type)  
    

?

第二步:從內(nèi)存池中取出一個對象內(nèi)存塊:

?

      
        1
      
       call_stub_t *
      
        new
      
       =
      
         NULL;  


      
      
        2
      
      
        3
      
       GF_VALIDATE_OR_GOTO (
      
        "
      
      
        call-stub
      
      
        "
      
      , frame, 
      
        out
      
      
        );  


      
      
        4
      
      
        5
      
      
        new
      
       = mem_get0 (frame->
      
        this
      
      ->ctx->stub_mem_pool);
      
        //
      
      
        從內(nèi)存池中拿出一個對象內(nèi)存塊  
      
    

?

如下面代碼取出一個調(diào)用存根的對象內(nèi)存塊(call_stub_t):

?

?

同樣使用的函數(shù)不是我們介紹的mem_get,而是mem_get0函數(shù),mem-get0封裝了mem_get,做參數(shù)判斷并且把需要使用的內(nèi)存初始化為0,代碼如下:

?

      
         1
      
      
        void
      
      *  


      
         2
      
       mem_get0 (
      
        struct
      
       mem_pool *
      
        mem_pool)  


      
      
         3
      
      
        {  


      
      
         4
      
      
        void
      
                   *ptr =
      
         NULL;  


      
      
         5
      
      
         6
      
      
        if
      
       (!
      
        mem_pool) {  


      
      
         7
      
                       gf_log_callingfn (
      
        "
      
      
        mem-pool
      
      
        "
      
      , GF_LOG_ERROR, 
      
        "
      
      
        invalid argument
      
      
        "
      
      
        );  


      
      
         8
      
      
        return
      
      
         NULL;  


      
      
         9
      
      
                }  


      
      
        10
      
      
        11
      
               ptr = mem_get(mem_pool);
      
        //
      
      
        得到一個內(nèi)存對象塊  
      
      
        12
      
      
        13
      
      
        if
      
      
         (ptr)  


      
      
        14
      
                       memset(ptr, 
      
        0
      
      , mem_pool->real_sizeof_type);
      
        //
      
      
        初始化0  
      
      
        15
      
      
        16
      
      
        return
      
      
         ptr;  


      
      
        17
      
       }  
    

?

?

第三步:放回對象內(nèi)存塊到內(nèi)存池中:

當(dāng)我們使用完一個對象以后就會重新放回內(nèi)存池中,例如還是以調(diào)用存根對象(call_stub_t)

?

      
         1
      
      
        void
      
      
         2
      
       call_stub_destroy (call_stub_t *
      
        stub)  


      
      
         3
      
      
        {  


      
      
         4
      
               GF_VALIDATE_OR_GOTO (
      
        "
      
      
        call-stub
      
      
        "
      
      , stub, 
      
        out
      
      
        );  


      
      
         5
      
      
         6
      
      
        if
      
       (stub->
      
        wind) {  


      
      
         7
      
      
                        call_stub_destroy_wind (stub);  


      
      
         8
      
               } 
      
        else
      
      
         {  


      
      
         9
      
      
                        call_stub_destroy_unwind (stub);  


      
      
        10
      
      
                }  


      
      
        11
      
      
        12
      
               stub->stub_mem_pool =
      
         NULL;  


      
      
        13
      
               mem_put (stub);
      
        //
      
      
        放回對象內(nèi)存塊到內(nèi)存池中  
      
      
        14
      
      
        out
      
      
        :  


      
      
        15
      
      
        return
      
      
        ;  


      
      
        16
      
       }  
    

?

第四步:銷毀內(nèi)存池:

如果整個內(nèi)存池對象都不需要了,那么銷毀掉這個內(nèi)存池,實(shí)現(xiàn)這個功能的函數(shù)是mem_pool_destroy:

?

      
         1
      
      
        void
      
      
         2
      
       mem_pool_destroy (
      
        struct
      
       mem_pool *
      
        pool)  


      
      
         3
      
      
        {  


      
      
         4
      
      
        if
      
       (!
      
        pool)  


      
      
         5
      
      
        return
      
      
        ;  


      
      
         6
      
      
         7
      
               gf_log (THIS->name, GF_LOG_INFO, 
      
        "
      
      
        size=%lu max=%d total=%
      
      
        "
      
      
        PRIu64,  


      
      
         8
      
                       pool->padded_sizeof_type, pool->max_alloc, pool->
      
        alloc_count);  


      
      
         9
      
      
        10
      
               list_del (&pool->global_list);
      
        //
      
      
        從全局內(nèi)存池對象中拖鏈  
      
      
        11
      
      
        12
      
               LOCK_DESTROY (&pool->
      
        lock
      
      );
      
        //
      
      
        銷毀鎖  
      
      
        13
      
               GF_FREE (pool->name);
      
        //
      
      
        釋放名字占用的內(nèi)存  
      
      
        14
      
               GF_FREE (pool->pool);
      
        //
      
      
        釋放內(nèi)存池分配的內(nèi)存,就是提供給用戶使用的那一段內(nèi)存  
      
      
        15
      
               GF_FREE (pool);
      
        //
      
      
        釋放內(nèi)存池對象占用的內(nèi)存  
      
      
        16
      
      
        17
      
      
        return
      
      
        ;  


      
      
        18
      
       }  
    

?

?

一般情況下內(nèi)存池對象會在程序退出的時候才會釋放和銷毀,還有一種情況是臨時分配的內(nèi)存池也有可能在系統(tǒng)運(yùn)行期間釋放和銷毀,因?yàn)椴荒鼙WC一個預(yù)先分配的內(nèi)存池就能夠滿足整個系統(tǒng)運(yùn)行期間那個對象所需要的內(nèi)存,可能在每一個階段這個對象使用特別多,以至于把內(nèi)存池預(yù)先分配的對象內(nèi)存塊使用完了,這時就需要臨時分配內(nèi)存池對象,過了這一段時間可能這個對象需要的個數(shù)就減少了,這時就需要釋放掉臨時分配的,已還給系統(tǒng)內(nèi)存。

?

OK!內(nèi)存池管理技術(shù)是提供內(nèi)存使用率和效率的重要手段,Glusterfs使用的內(nèi)存池技術(shù)采用的是linux內(nèi)核管理小內(nèi)存塊的分配算法slab,就是基于對象分配內(nèi)存的技術(shù)。可以先去熟悉slab的原理,就能更好的理解Glusterfs的內(nèi)存池技術(shù)了!

GlusterFS之內(nèi)存池(mem-pool)使用實(shí)例分析


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

主站蜘蛛池模板: 老司机久久影院 | 久草在线在线精品观看 | 伊人97在线 | 乱人伦视频69 | 99热国产这里只有精品99 | 中文一区在线 | 四虎国产在线观看 | 久久国产综合精品欧美 | 久久99精品一区二区三区 | 久久www免费人成_看片高清 | 鲁鲁狠色综合色综合网站 | 亚洲欧洲日产国码天堂 | 97免费在线观看 | a毛片免费全部在线播放毛 a毛片免费在线观看 | 999热成人精品国产免 | 欧美人与zoxxxx另类9 | 欧美日韩免费在线观看 | 五月天亚洲 | 日日操操 | 国产综合在线观看 | 99j久久精品久久久久久 | 日韩精品一区二区三区在线观看 | 四虎免费最新在线永久 | 毛片爱做的片 | 欧美一区二区三区国产精品 | 天天干天天拍 | 亚洲日本在线播放 | 好好的曰com久久 | 亚洲永久视频 | 亚洲精品不卡久久久久久 | 日本一级毛片不卡免费 | 亚洲七七久久综合桃花 | 四虎影视成人永久在线观看 | 久久精品国产亚洲aa | 波多野结衣高清在线播放 | 天天舔天天操 | 久久www免费人成精品 | 国产精自产拍久久久久久蜜 | 亚洲无成人网77777 | 天天躁日日躁狠狠躁黑人躁 | 欧美日韩国产高清一区二区三区 |