• <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>

            Daly的游戲人生

            替代系統(tǒng)malloc/new--選擇合適的內(nèi)存跟蹤方案

             
            替代系統(tǒng)自帶的malloc/new原因無(wú)非兩個(gè): 
            reason 1. 做內(nèi)存profile或查找問(wèn)題   
            reason 2. 自定義的分配方案提高性能

            不過(guò)文章[1]中說(shuō)明了,替代全局new不是一個(gè)好做法. 其實(shí)要達(dá)到以上兩點(diǎn)目的,筆者認(rèn)為用valgrind工具鏈就可以了。

            解決方案:
            1. 用valgrind和massif
                 valgrind的memcheck做內(nèi)存泄露和bug的查找, 里面的massif工具包做內(nèi)存性能profile, 足矣。比自己山寨的一個(gè)profiler要好。
                 注意:tcmalloc目前還不能很好支持valgrind,  實(shí)測(cè)中jemalloc可以

            2.  linux下C的程序可以用wrap的方式(相當(dāng)于python的decorator)
                 編譯加上選項(xiàng):gcc -Wl,-wrap,malloc
                 可以做到對(duì)malloc這個(gè)函數(shù),linker會(huì)調(diào)用__wrap_malloc代替之, 若要調(diào)用原來(lái)的malloc函數(shù)__real_malloc
                 缺點(diǎn):依賴于編譯器支持; 對(duì)c++的new不起作用 --> 不實(shí)用
                 啟示:這個(gè)方法作為function裝飾器,對(duì)于調(diào)試別的問(wèn)題倒有幫助。(例如不改變函數(shù)的情況下,wrap一層,輸出些調(diào)試信息)
            3. 用__malloc_hook
                參考: http://linux.die.net/man/3/__malloc_hook
                 #include <malloc.h>
                 void *(*__malloc_hook)(size_t size, const void *caller);
                 缺點(diǎn):依賴GNU編譯工具鏈;  容易死循環(huán)(想利用原有malloc,要參考例子中,把原__malloc_hook變量保存起來(lái)使用,并恢復(fù)現(xiàn)場(chǎng))
            

            4. LD_PRELOAD注入.so ,替代原
                 環(huán)境變量LD_PRELOAD指定程序運(yùn)行時(shí)優(yōu)先加載的動(dòng)態(tài)連接庫(kù),這個(gè)動(dòng)態(tài)鏈接庫(kù)中的符號(hào)優(yōu)先級(jí)是最高的。標(biāo)準(zhǔn)C的各種函數(shù)都是存放在libc.so.6的文件中,在程序運(yùn)行時(shí)自動(dòng)鏈接。使用LD_PRELOAD后,自己編寫(xiě)的malloc的加載順序高于glibc中的malloc,這樣就實(shí)現(xiàn)了替換。用法 LD_PRELOAD=" ./mymalloc.so"
                  缺點(diǎn):在生產(chǎn)環(huán)境不現(xiàn)實(shí)。因?yàn)長(zhǎng)D_PRELOAD相當(dāng)于庫(kù)注入,有安全性問(wèn)題,是必須禁止的。(生產(chǎn)環(huán)境很多時(shí)候用-static連接)
            5. 用宏或另外的函數(shù)替代new/malloc
               比如定義一個(gè)宏或者指定的函數(shù),規(guī)定所有的分配釋放都調(diào)用他。這樣相當(dāng)于給項(xiàng)目引入了額外的代碼規(guī)則(而且是一立項(xiàng)就要遵循這個(gè)規(guī)則,否則該方法無(wú)效),不能很自然的new/delete, 如果分配和釋放調(diào)用得不一致,會(huì)產(chǎn)生問(wèn)題的。某產(chǎn)品組就是用宏,然后加上__FILE__, __LINE__之類(lèi)的信息。

             有時(shí)候valgrind的效率是個(gè)問(wèn)題(尤其生產(chǎn)環(huán)境),這種方案有其價(jià)值所在, 就是代碼看上去比較ugly罷了

               用宏的例子:
               #define _New(Type, Catergory)                    (Type*)MyMemController::New((new Type), #Type, 1, sizeof(Type),   Catergory, __FILE__, __LINE__, false)
               #define _NewArray(Type, N, Catergory)          (Type*)MyMemController::New((new Type[N]), #Type, N, sizeof(Type)*(N), Catergory, __FILE__, __LINE__, true)

               
            MALLOC的替代品:
                 自己寫(xiě)一個(gè)malloc其實(shí)很復(fù)雜,要考慮線程安全等各種問(wèn)題,性能到頭來(lái)可能更差。google 的tcmalloc,  facebook使用的jemalloc.   多線程下性能較好,可以考慮使用。
                 缺點(diǎn):筆者嘗試過(guò)。tcmalloc不能正確用valgrind,只能用自帶gperftools(運(yùn)行中會(huì)core)
                             jemalloc可以使用valgrind,不過(guò)還沒(méi)完全驗(yàn)證是否都準(zhǔn)確。
            tcmalloc相關(guān):
                在64位系統(tǒng)上要裝libunwind, 對(duì)x86-64架構(gòu)使用還有些問(wèn)題

            源碼包的INSTALL文檔里面也提到了這個(gè)問(wèn)題。
             CAUTION: if you install libunwind from the url above, be aware that
               you may have trouble if you try to statically link your binary with
               perftools: that is, if you link with 'gcc -static -lgcc_eh ...'.
               This is because both libunwind and libgcc implement the same C++
               exception handling APIs, but they implement them differently on
               some platforms.  This is not likely to be a problem on ia64, but
               may be on x86-64.

            主要是64位機(jī)frame-pointer的影響, 他的profile工具里的backtrace用libunwind這個(gè)庫(kù),這個(gè)庫(kù)又有版本問(wèn)題,各種囧啊....
            筆者試過(guò)系統(tǒng)x86-64, freebsd,用靜態(tài)鏈接。實(shí)際用了一下,問(wèn)題很多很折騰,等他fix了再說(shuō)吧.

            windows下可以參考:

            jemalloc暫時(shí)未發(fā)現(xiàn)有什么兼容性問(wèn)題,運(yùn)行得挺好的。
             
            Reference
            [1] <不要重載全局operator new>

            [2] effective c++條款50:了解new和delete的合理替換時(shí)機(jī)

            [3] 游戲引擎中的內(nèi)存分配策略
            [4] 更好的內(nèi)存管理jemalloc
            [5] tcmalloc官網(wǎng)(gperftools)

            posted on 2012-07-02 13:01 Daly 閱讀(7509) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): C/C++

            久久人人妻人人爽人人爽| 精品久久久久久久国产潘金莲| 色偷偷偷久久伊人大杳蕉| 无码国产69精品久久久久网站| 麻豆精品久久久一区二区| 大美女久久久久久j久久| 亚洲婷婷国产精品电影人久久| 精品无码久久久久久尤物| 久久久久亚洲AV成人网人人软件| 久久狠狠爱亚洲综合影院| 精品久久久久国产免费| 久久婷婷五月综合色高清| 久久婷婷色综合一区二区| 精品一区二区久久| 亚洲国产另类久久久精品| 久久精品国产精品亚洲艾草网美妙 | 久久精品一本到99热免费| 久久久久亚洲av成人无码电影| 国产69精品久久久久777| 久久久久久久久久久| 欧美粉嫩小泬久久久久久久 | 99久久亚洲综合精品成人| 久久精品无码专区免费青青| 性做久久久久久免费观看| 国产精品久久久99| A级毛片无码久久精品免费| 精品久久久久久久久午夜福利| 综合网日日天干夜夜久久 | 91精品国产综合久久精品| 中文字幕人妻色偷偷久久| 97视频久久久| 一本一本久久a久久综合精品蜜桃| 亚洲?V乱码久久精品蜜桃 | 久久精品国产亚洲AV无码麻豆| 性做久久久久久久久浪潮| 久久受www免费人成_看片中文| 93精91精品国产综合久久香蕉| 国产69精品久久久久99| 99久久精品国产一区二区三区| 色偷偷888欧美精品久久久| 国产成人精品久久|