• <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>
            posts - 14,  comments - 57,  trackbacks - 0
              昨天一個(gè)同事一大早在群里推薦了一個(gè)google project上的開(kāi)源內(nèi)存分配器(http://code.google.com/p/google-perftools/),據(jù)說(shuō)google的很多產(chǎn)品都用到了這個(gè)內(nèi)存分配庫(kù),而且經(jīng)他測(cè)試,我們的游戲客戶(hù)端集成了這個(gè)最新內(nèi)存分配器后,F(xiàn)PS足足提高了將近10幀左右,這可是個(gè)了不起的提升,要知道3D組的兄弟忙了幾周也沒(méi)見(jiàn)這么大的性能提升。

            如果我們自己本身用的crt提供的內(nèi)存分配器,這個(gè)提升也算不得什么。問(wèn)題是我們內(nèi)部系統(tǒng)是有一個(gè)小內(nèi)存管理器的,一般來(lái)說(shuō)小內(nèi)存分配的算法都大同小異,現(xiàn)成的實(shí)現(xiàn)也很多,比如linux內(nèi)核的slab、SGI STL的分配器、ogre自帶的內(nèi)存分配器,我們自己的內(nèi)存分配器也和前面列舉的實(shí)現(xiàn)差不多。讓我們來(lái)看看這個(gè)項(xiàng)目有什么特別的吧。

            一、使用方法

            打開(kāi)主頁(yè),由于公司網(wǎng)絡(luò)禁止SVN從外部更新,所以只能下載了打包的源代碼。解壓后,看到有個(gè)doc目錄,進(jìn)去,打開(kāi)使用文檔,發(fā)現(xiàn)使用方法極為簡(jiǎn)單:
            To use TCMalloc, just link TCMalloc into your application via the "-ltcmalloc" linker flag.再看算法,也沒(méi)什么特別的,還是和slab以及SGI STL分配器類(lèi)似的算法。
            unix環(huán)境居然只要鏈接這個(gè)tcmalloc庫(kù)就可以了!,太方便了,不過(guò)我手頭沒(méi)有l(wèi)inux環(huán)境,文檔上也沒(méi)提到windows環(huán)境怎么使用,
            打開(kāi)源代碼包,有個(gè)vs2003解決方案,打開(kāi),隨便挑選一個(gè)測(cè)試項(xiàng)目,查看項(xiàng)目屬性,發(fā)現(xiàn)僅僅有2點(diǎn)不同:
            1、鏈接器命令行里多了
              "..\..\release\libtcmalloc_minimal.lib",就是鏈接的時(shí)候依賴(lài)了這個(gè)內(nèi)存優(yōu)化庫(kù)。
            2、鏈接器->輸入->強(qiáng)制符號(hào)引用 多了 __tcmalloc。
            這樣就可以正確的使用tcmalloc庫(kù)了,測(cè)試了下,測(cè)試項(xiàng)目運(yùn)行OK!

            二、如何替換CRT的malloc

            從前面的描述可知,項(xiàng)目強(qiáng)制引用了__tcmalloc, 搜索了測(cè)試代碼,沒(méi)發(fā)現(xiàn)用到_tcmalloc相關(guān)的函數(shù)和變量,這個(gè)選項(xiàng)應(yīng)該是為了防止dll被優(yōu)化掉(因?yàn)榇a里沒(méi)有什么地方用到這個(gè)dll的符號(hào))。
            初看起來(lái),鏈接這個(gè)庫(kù)后,不會(huì)影響任何現(xiàn)有代碼:我們沒(méi)有引用這個(gè)Lib庫(kù)的頭文件,也沒(méi)有使用過(guò)這個(gè)dll的導(dǎo)出函數(shù)。那么這個(gè)dll是怎么優(yōu)化應(yīng)用程序性能的呢?
            實(shí)際調(diào)試,果然發(fā)現(xiàn)問(wèn)題了,看看如下代碼
                void* pData = malloc(100);
            00401085 6A 64            push        64h 
            00401087 FF 15 A4 20 40 00 call        dword ptr [__imp__malloc (4020A4h)]
            跟蹤 call malloc這句,step進(jìn)去,發(fā)現(xiàn)是
            78134D09 E9 D2 37 ED 97   jmp         `anonymous namespace'::LibcInfoWithPatchFunctions<8>::Perftools_malloc (100084E0h)
            果然,從這里開(kāi)始,就跳轉(zhuǎn)到libtcmalloc提供的Perftools_malloc了。
            原來(lái)是通過(guò)API掛鉤來(lái)實(shí)現(xiàn)無(wú)縫替換系統(tǒng)自帶的malloc等crt函數(shù)的,而且還是通過(guò)大家公認(rèn)的不推薦的改寫(xiě)函數(shù)入口指令來(lái)實(shí)現(xiàn)的,一般只有在游戲外掛和金山詞霸之類(lèi)的軟件才會(huì)用到這樣的掛鉤技術(shù),
            而且金山詞霸經(jīng)常需要更新補(bǔ)丁解決不同系統(tǒng)兼容問(wèn)題。

            三、性能差別原因

            如前面所述,tcmalloc確實(shí)用了很hacker的辦法來(lái)實(shí)現(xiàn)無(wú)縫的替換系統(tǒng)自帶的內(nèi)存分配函數(shù)(本人在使用這類(lèi)技術(shù)通常是用來(lái)干壞事的。。。),但是這也不足以解釋為什么它的效率比我們自己的好那么多。
            回到tcmalloc 的手冊(cè),tcmalloc除了使用常規(guī)的小內(nèi)存管理外,對(duì)多線程環(huán)境做了特殊處理,這和我原來(lái)見(jiàn)到的內(nèi)存分配器大有不同,一般的內(nèi)存分配器作者都會(huì)偷懶,把多線程問(wèn)題扔給使用者,大多是加
            個(gè)bool型的模板參數(shù)來(lái)表示是否是多線程環(huán)境,還美其名曰:可定制,末了還得吹噓下模板的優(yōu)越性。
            tcmalloc是怎么做的呢? 答案是每線程一個(gè)ThreadCache,大部分操作系統(tǒng)都會(huì)支持thread local storage 就是傳說(shuō)中的TLS,這樣就可以實(shí)現(xiàn)每線程一個(gè)分配器了,
            這樣,不同線程分配都是在各自的threadCache里分配的。我們的項(xiàng)目的分配器由于是多線程環(huán)境的,所以不管三七二十一,全都加鎖了,性能自然就低了。

            僅僅是如此,還是不足以將tcmalloc和ptmalloc2分個(gè)高下,后者也是每個(gè)線程都有threadCache的。
            關(guān)于這個(gè)問(wèn)題,doc里有一段說(shuō)明,原文貼出來(lái):
            ptmalloc2 also reduces lock contention by using per-thread arenas but there is a big problem with ptmalloc2's use of per-thread arenas. In ptmalloc2 memory can never move from one arena to another. This can lead to huge amounts of wasted space.
            大意是這樣的:ptmalloc2 也是通過(guò)tls來(lái)降低線程鎖,但是ptmalloc2各個(gè)線程的內(nèi)存是獨(dú)立的,也就是說(shuō),第一個(gè)線程申請(qǐng)的內(nèi)存,釋放的時(shí)候還是必須放到第一個(gè)線程池中(不可移動(dòng)),這樣可能導(dǎo)致大量?jī)?nèi)存浪費(fèi)。
             

            四、代碼細(xì)節(jié)

            1、無(wú)縫替換malloc等crt和系統(tǒng)分配函數(shù)。

               前面提到tcmalloc會(huì)無(wú)縫的替換掉原有dll中的malloc,這就意味著使用tcmalloc的項(xiàng)目必須是 MD(多線程dll)或者M(jìn)Dd(多線程dll調(diào)試)。tcmalloc的dll定義了一個(gè)
            static TCMallocGuard module_enter_exit_hook;
            的靜態(tài)變量,這個(gè)變量會(huì)在dll加載的時(shí)候先于DllMain運(yùn)行,在這個(gè)類(lèi)的構(gòu)造函數(shù),會(huì)運(yùn)行PatchWindowsFunctions來(lái)掛鉤所有dll的 malloc、free、new等分配函數(shù),這樣就達(dá)到了替換功能,除此之外,
            為了保證系統(tǒng)兼容性,掛鉤API的時(shí)候還實(shí)現(xiàn)了智能分析指令,否則寫(xiě)入第一條Jmp指令的時(shí)候可能會(huì)破環(huán)后續(xù)指令的完整性。

            2、LibcInfoWithPatchFunctions 和ThreadCache。

            LibcInfoWithPatchFunctions模板類(lèi)包含tcmalloc實(shí)現(xiàn)的優(yōu)化后的malloc等一系列函數(shù)。LibcInfoWithPatchFunctions的模板參數(shù)在我看來(lái)沒(méi)什么用處,tcmalloc默認(rèn)可以掛鉤
            最多10個(gè)帶有malloc導(dǎo)出函數(shù)的庫(kù)(我想肯定是夠用了)。ThreadCache在每個(gè)線程都會(huì)有一個(gè)TLS對(duì)象:
            __thread ThreadCache* ThreadCache::threadlocal_heap_。

            3、可能的問(wèn)題


            設(shè)想下這樣一個(gè)情景:假如有一個(gè)dll 在tcmalloc之前加載,并且在分配了內(nèi)存(使用crt提供的malloc),那么在加載tcmalloc后,tcmalloc會(huì)替換所有的free函數(shù),然后,在某個(gè)時(shí)刻,
            在前面的那個(gè)dll代碼中釋放該內(nèi)存,這豈不是很危險(xiǎn)。實(shí)際測(cè)試發(fā)現(xiàn)沒(méi)有任何問(wèn)題,關(guān)鍵在這里:
             span = Static::pageheap()->GetDescriptor(p);
                if (!span) {
                  // span can be NULL because the pointer passed in is invalid
                  // (not something returned by malloc or friends), or because the
                  // pointer was allocated with some other allocator besides
                  // tcmalloc.  The latter can happen if tcmalloc is linked in via
                  // a dynamic library, but is not listed last on the link line.
                  // In that case, libraries after it on the link line will
                  // allocate with libc malloc, but free with tcmalloc's free.
                  (*invalid_free_fn)(ptr);  // Decide how to handle the bad free request
                  return;
                }
            tcmalloc會(huì)通過(guò)span識(shí)別這個(gè)內(nèi)存是否自己分配的,如果不是,tcmalloc會(huì)調(diào)用該dll原始對(duì)應(yīng)函數(shù)(這個(gè)很重要)釋放。這樣就解決了這個(gè)棘手的問(wèn)題。

            五、其他

            其實(shí)tcmalloc使用的每個(gè)技術(shù)點(diǎn)我從前都用過(guò),但是我從來(lái)沒(méi)想過(guò)用API掛鉤來(lái)實(shí)現(xiàn)這樣一個(gè)有趣的內(nèi)存優(yōu)化庫(kù)(即使想過(guò),也是一閃而過(guò)就否定了)。
            從tcmalloc得到靈感,結(jié)合常用的外掛技術(shù),可以很輕松的開(kāi)發(fā)一個(gè)獨(dú)立工具:這個(gè)工具可以掛載到指定進(jìn)程進(jìn)行內(nèi)存優(yōu)化,在我看來(lái),這可能可以作為一個(gè)外掛輔助工具來(lái)優(yōu)化那些
            內(nèi)存優(yōu)化做的很差導(dǎo)致幀速很低的國(guó)產(chǎn)游戲。
            posted on 2010-07-10 17:32 feixuwu 閱讀(10074) 評(píng)論(14)  編輯 收藏 引用 所屬分類(lèi): 游戲開(kāi)發(fā)

            FeedBack:
            # re: 推薦一個(gè)跨平臺(tái)內(nèi)存分配器
            2010-07-10 19:52 | chaogu
            好像內(nèi)存分配策略沒(méi)有講明白.....
              回復(fù)  更多評(píng)論
              
            # re: 推薦一個(gè)跨平臺(tái)內(nèi)存分配器
            2010-07-10 20:39 | feixuwu
            @chaogu
            恩,這篇主要不是講常規(guī)小內(nèi)存分配的,那個(gè)到處都在講,沒(méi)啥新意了,文章資料里提到的很多都是常規(guī)小內(nèi)存實(shí)現(xiàn),也可以直接看代碼或者侯捷的STL源碼剖析,有詳細(xì)內(nèi)容的。  回復(fù)  更多評(píng)論
              
            # re: 推薦一個(gè)跨平臺(tái)內(nèi)存分配器
            2010-08-07 08:27 | maxime
            小內(nèi)存分配器主要作用是“減小內(nèi)存碎片化趨勢(shì),減小薄記內(nèi)存比例,提高小內(nèi)存利用率”,從性能上說(shuō),系統(tǒng)內(nèi)存分配器已針對(duì)小內(nèi)存分配進(jìn)行優(yōu)化,單純使用自定義的小內(nèi)存分配器,對(duì)性能幫助不會(huì)很大。內(nèi)置分配器意義還是體現(xiàn)在,實(shí)現(xiàn)無(wú)鎖分配,避免API調(diào)用切換開(kāi)銷(xiāo)。
            CRT自身new-delete會(huì)用到500個(gè)時(shí)鐘周期,而一個(gè)CS會(huì)消耗50個(gè)時(shí)鐘周期,一個(gè)mutex會(huì)用到2000個(gè)時(shí)鐘周期,以上是無(wú)競(jìng)爭(zhēng)的情況。所以,如果用mutex做互斥,那還不如用系統(tǒng)的分配器;如果用CS,也不見(jiàn)會(huì)好多少,因?yàn)镃S會(huì)隨鎖競(jìng)爭(zhēng)加劇大幅增加時(shí)間,甚至?xí)^(guò)mutex。
            所以結(jié)論是,對(duì)于單線程,內(nèi)置分配器有一定的價(jià)值;對(duì)于多線程,帶鎖內(nèi)置分配器基本上可以無(wú)視了(至少對(duì)于winxp以后是這樣,win2k好像要打補(bǔ)丁)呵呵,從你說(shuō)的情況來(lái)看,很有可能你們?cè)瓉?lái)的分配器用mutex幫倒忙了。

            tcmalloc中的唯一亮點(diǎn)應(yīng)該是,如何做到跨線程歸還內(nèi)存,又能保持高性能,猜想可能使用了某種二級(jí)分配策略,內(nèi)存塊可以屬于任何線程的內(nèi)存池,歸還到那個(gè)線程內(nèi)存池,就由這個(gè)內(nèi)存池管理。由于各個(gè)線程的分配和釋放多半不平衡,有線程池會(huì)撐滿(mǎn),有的會(huì)不足。估計(jì)撐滿(mǎn)的就會(huì)歸還到公共內(nèi)存池。第一級(jí)分配無(wú)鎖,如果內(nèi)存池不足了,就進(jìn)入第二級(jí)帶鎖批量分配,而且第二級(jí)分配會(huì)先從公共內(nèi)存池獲取,如果還不夠,這才使用系統(tǒng)內(nèi)存分配,這該算是第三級(jí)分配了。


            最后,tcmalloc也是可以用于MT版本的哦,詳見(jiàn)(要翻墻才能看見(jiàn))http://groups.google.com/group/google-perftools/browse_thread/thread/41cd3710af85e57b  回復(fù)  更多評(píng)論
              
            # re: 推薦一個(gè)跨平臺(tái)內(nèi)存分配器
            2010-08-07 08:31 | maxime
            為避免大家翻墻,將原文貼在下面了。另外,如果下載chrome的源代碼,其中就包含了tcmalloc的,它里面已經(jīng)幫你把這篇文章要做的都做了,用腳本的形式。

            Hi,

            I wanted to post a little information about some changes that I'm
            working on finishing up for the windows version of tcmalloc. If
            you've ever had trouble overriding malloc/free on windows, you might
            find this useful.


            With Chrome, we wanted to override the default C runtime allocators
            with TCMalloc. Chrome links the C runtime statically (/MT) in
            VS2005. Unfortunately, VS2005 does not have a static mechanism to
            override all allocators. This sounds easy, but it is not - VS2005 and
            VS2008 both use C runtimes with internal functions that cannot be
            overridden. We also didn't like the runtime patching approach which
            tcmalloc currently uses. So, to get static linkage to work, we take
            the C runtime library from Microsoft and remove all heap allocators
            from it using the LIB.EXE tool. We then implement stub functions for
            the non-overridable functions in the C runtime and manually link
            Chrome to use the new library.


            If you want to do this too, here are the steps:


            Steps
            1) Create a slimmed down version of the C Runtime Library. The C
            Runtime Library ships with VS2005 in $VCInstallDir\lib\libcmt.lib. We
            use the script below to do this.
            2) In TCMalloc's config.h, define WIN32_OVERRIDE_ALLOCATORS
            3) Modify your DLL or EXE build with the following:
            a) link in tcmalloc.lib by adding a Project Dependency to it.
            b) in Properties -> Linker -> Input, set "Ignore Specific Library"
            to "libcmt.lib"
            c) in Properties -> Linker -> Input, add "mylibcmt.lib" to the
            "Additional Dependencies" line.


            SLIM_CRT.BAT
            REM
            REM This script takes libcmt.lib for VS2005 and removes the allocation
            related
            REM functions from it.
            REM
            REM Usage: prep_libcmt.bat <VCInstallDir> <OutputFile>
            REM
            REM VCInstallDir is the path where VC is installed, typically:
            REM C:\Program Files\Microsoft Visual Studio 8\VC\
            REM
            REM OutputFile is the directory where the modified libcmt file should
            be stored.
            REM


            SET LIBCMT=%1lib\libcmt.lib
            SET LIBCMTPDB=%1lib\libcmt.pdb
            SET OUTDIR=%2
            SET OUTCMT=%2\libcmt.lib


            MKDIR %OUTDIR%
            COPY %LIBCMT% %OUTDIR%
            COPY %LIBCMTPDB% %OUTDIR%
            LIB /IGNORE:4006,4221 /REMOVE:build\intel\mt_obj\malloc.obj %OUTCMT%
            LIB /IGNORE:4006,4221 /REMOVE:build\intel\mt_obj\free.obj %OUTCMT%
            LIB /IGNORE:4006,4221 /REMOVE:build\intel\mt_obj\realloc.obj %OUTCMT%
            LIB /IGNORE:4006,4221 /REMOVE:build\intel\mt_obj\calloc.obj %OUTCMT%
            LIB /IGNORE:4006,4221 /REMOVE:build\intel\mt_obj\new.obj %OUTCMT%
            LIB /IGNORE:4006,4221 /REMOVE:build\intel\mt_obj\delete.obj %OUTCMT%
            LIB /IGNORE:4006,4221 /REMOVE:build\intel\mt_obj\new2.obj %OUTCMT%
            LIB /IGNORE:4006,4221 /REMOVE:build\intel\mt_obj\delete2.obj %OUTCMT%
            LIB /IGNORE:4006,4221 /REMOVE:build\intel\mt_obj\align.obj %OUTCMT%
            LIB /IGNORE:4006,4221 /REMOVE:build\intel\mt_obj\msize.obj %OUTCMT%


            LIB /IGNORE:4006,4221 /REMOVE:build\intel\mt_obj\heapinit.obj %OUTCMT%
            LIB /IGNORE:4006,4221 /REMOVE:build\intel\mt_obj\expand.obj %OUTCMT%
            LIB /IGNORE:4006,4221 /REMOVE:build\intel\mt_obj\heapchk.obj %OUTCMT%
            LIB /IGNORE:4006,4221 /REMOVE:build\intel\mt_obj\heapwalk.obj %OUTCMT%
            LIB /IGNORE:4006,4221 /REMOVE:build\intel\mt_obj\heapmin.obj %OUTCMT%
            LIB /IGNORE:4006,4221 /REMOVE:build\intel\mt_obj\sbheap.obj %OUTCMT%
            LIB /IGNORE:4006,4221 /REMOVE:build\intel\mt_obj\smalheap.obj %OUTCMT%
              回復(fù)  更多評(píng)論
              
            # re: 推薦一個(gè)跨平臺(tái)內(nèi)存分配器
            2010-08-07 09:15 | feixuwu
            @maxime
            同意加鎖的自定義分配器還不如不用的說(shuō)法(所以說(shuō)設(shè)計(jì)討論在項(xiàng)目中是需要的,除了開(kāi)發(fā)者,我們大家都不知道項(xiàng)目的多線程分配加鎖了:))。

            對(duì)“系統(tǒng)內(nèi)存分配器已針對(duì)小內(nèi)存分配進(jìn)行優(yōu)化”,這個(gè)我觀點(diǎn)覺(jué)得有可能(畢竟沒(méi)有驗(yàn)證),不過(guò)我倒覺(jué)得crt分配小內(nèi)存的至少還是會(huì)有個(gè)head的,這個(gè)浪費(fèi)免不了了(當(dāng)然tcmalloc現(xiàn)在也是有頭的,一般自己實(shí)現(xiàn)的內(nèi)存分配器是不會(huì)有頭的),從比例上來(lái)說(shuō)浪費(fèi)的還是比較多的,這個(gè)可以做個(gè)實(shí)驗(yàn)驗(yàn)證,一次分配50M和多次分配10byte至50M,2者進(jìn)程的內(nèi)存差距還是比較明顯的。
            好在現(xiàn)在PC和服務(wù)器內(nèi)存越來(lái)越大,內(nèi)存分配器的主要焦點(diǎn)都集中在速度上了。

            tcmalloc跨線程歸還內(nèi)存,確實(shí)是因?yàn)樗芯€程公用了底層的一個(gè)分配器,所以跨線程歸還是無(wú)需加鎖的(從手冊(cè)上看的,不知道博文提了沒(méi)有)。
            關(guān)于tcmalloc亮點(diǎn),我倒覺(jué)得算法上的小優(yōu)化其實(shí)倒沒(méi)那么振奮,給我沖擊最大的是產(chǎn)品的可用性,以往一個(gè)產(chǎn)品要使用新的內(nèi)存分配器,一般需要改很多代碼,最常見(jiàn)的是將已有類(lèi)從一個(gè)SmallObject之類(lèi)的類(lèi)繼承,很麻煩,這方面tcmalloc干的不錯(cuò)。

            最后感謝maxime提供了MT使用tcmalloc的資料,以我從前的看法,靜態(tài)編譯的版本是無(wú)法使用tcmalloc的。  回復(fù)  更多評(píng)論
              
            # re: 推薦一個(gè)跨平臺(tái)內(nèi)存分配器
            2010-08-08 11:19 | kingzt
            不知道博主能否做出一個(gè)外掛式的內(nèi)存優(yōu)化工具分享一下,現(xiàn)在的國(guó)產(chǎn)游戲優(yōu)化確實(shí)是讓人無(wú)語(yǔ),如果有這個(gè)的話情況估計(jì)會(huì)好很多  回復(fù)  更多評(píng)論
              
            # re: 推薦一個(gè)跨平臺(tái)內(nèi)存分配器
            2010-08-08 11:22 | kingzt
            博主能否實(shí)現(xiàn)一個(gè)這樣的外掛式內(nèi)存優(yōu)化工具分享給國(guó)內(nèi)的游戲玩家,現(xiàn)在有的游戲優(yōu)化確實(shí)是讓人無(wú)語(yǔ),如果有這個(gè)的話情況估計(jì)會(huì)好很多  回復(fù)  更多評(píng)論
              
            # re: 推薦一個(gè)跨平臺(tái)內(nèi)存分配器
            2010-09-15 01:08 | 求助啊
            請(qǐng)問(wèn)如何在MFC程序中使用此tcmalloc?
            能說(shuō)下嗎?
            多謝了。
              回復(fù)  更多評(píng)論
              
            # re: 推薦一個(gè)跨平臺(tái)內(nèi)存分配器
            2010-09-17 21:03 | Roger
            @求助啊
            我在我的VS2003工程中用到TCMalloc,此功能有很多其他DLL模塊.
            出現(xiàn)2個(gè)問(wèn)題:
            1。 有些DLL模塊在TCMall模塊之前加載,并且分配了內(nèi)存,此時(shí)不能被TCMalloc管理
            2。 在進(jìn)程退出時(shí)異常崩潰
            出現(xiàn)在:(*invalid_free_fn)(ptr)
            好像是地址無(wú)效了.
            我猜想是:hook其他dll模塊的函數(shù),而此時(shí)的dll模塊已經(jīng)卸載了,因此此指針函數(shù)無(wú)效.
            // This lets you call back to a given function pointer if ptr is invalid.
            // It is used primarily by windows code which wants a specialized callback.
            inline void do_free_with_callback(void* ptr, void (*invalid_free_fn)(void*)) {
            if (ptr == NULL) return;
            ASSERT(Static::pageheap() != NULL); // Should not call free() before malloc()
            const PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift;
            Span* span = NULL;
            size_t cl = Static::pageheap()->GetSizeClassIfCached(p);

            if (cl == 0) {
            span = Static::pageheap()->GetDescriptor(p);
            if (!span) {
            // span can be NULL because the pointer passed in is invalid
            // (not something returned by malloc or friends), or because the
            // pointer was allocated with some other allocator besides
            // tcmalloc. The latter can happen if tcmalloc is linked in via
            // a dynamic library, but is not listed last on the link line.
            // In that case, libraries after it on the link line will
            // allocate with libc malloc, but free with tcmalloc's free.
            (*invalid_free_fn)(ptr); // Decide how to handle the bad free request
            return;
            }  回復(fù)  更多評(píng)論
              
            # re: 推薦一個(gè)跨平臺(tái)內(nèi)存分配器
            2010-09-17 21:03 | Roger
            我的QQ:roger201008@qq.com  回復(fù)  更多評(píng)論
              
            # re: 推薦一個(gè)跨平臺(tái)內(nèi)存分配器[未登錄](méi)
            2011-08-25 22:12 | Lee
            很奇怪,我在MFC工程里面把tcmalloc編譯進(jìn)去,vc居然報(bào)內(nèi)存泄漏。
            我的環(huán)境是vc2010.
            不知道可否有人碰到這個(gè)情況啊?  回復(fù)  更多評(píng)論
              
            # re: 推薦一個(gè)跨平臺(tái)內(nèi)存分配器
            2012-11-16 18:06 | gohay
            大哥,tcmalloc 不是通過(guò)API掛鉤來(lái)實(shí)現(xiàn)無(wú)縫替換系統(tǒng)自帶的malloc等crt函數(shù)的。
            tcmalloc是通過(guò)靜態(tài)全局變量的初始化早于main函數(shù)這個(gè)原理搞的,它定義了一個(gè)全局變量(tcmalloc.cc 文件中920行) static TCMallocGuard module_enter_exit_hook;
            在TCMallocGuard這個(gè)類(lèi)的構(gòu)造函數(shù)中做了一大堆事情用來(lái)替換系統(tǒng)自帶的malloc等crt函數(shù)  回復(fù)  更多評(píng)論
              
            # re: 推薦一個(gè)跨平臺(tái)內(nèi)存分配器
            2012-11-29 14:21 | feiwu
            @gohay
            抱歉我沒(méi)說(shuō)清楚。
            你說(shuō)的那個(gè)是在tcmalooc在linux下的做法。在windows下就是改寫(xiě)指令來(lái)處理的。
            linux下不能掛鉤,但是可以先加載來(lái)覆蓋系統(tǒng)crtAPI,相比之下,linux下做這個(gè)更容易,linux甚至都不同編譯進(jìn)去就可以直接用。  回復(fù)  更多評(píng)論
              
            # re: 推薦一個(gè)跨平臺(tái)內(nèi)存分配器
            2013-05-17 22:02 | leehark
            在windows下怎么做堆檢測(cè)呢?  回復(fù)  更多評(píng)論
              
            <2010年7月>
            27282930123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            文章轉(zhuǎn)載請(qǐng)注明出處

            常用鏈接

            留言簿(11)

            隨筆分類(lèi)

            隨筆檔案

            搜索

            •  

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            久久婷婷激情综合色综合俺也去| 99久久亚洲综合精品网站| 无夜精品久久久久久| 色播久久人人爽人人爽人人片aV| 久久精品国产第一区二区| 模特私拍国产精品久久| 三上悠亚久久精品| 久久无码AV中文出轨人妻| 久久精品成人欧美大片| 亚洲国产精品久久久久| 亚洲AV无码1区2区久久| 99国内精品久久久久久久| 久久婷婷色香五月综合激情| 久久91精品国产91久久小草| 久久99热这里只有精品国产| 国内精品久久久久久久涩爱| 少妇内射兰兰久久| 一本大道久久东京热无码AV| 久久婷婷综合中文字幕| 99久久夜色精品国产网站| 精品无码久久久久久久动漫| 久久人人爽爽爽人久久久| 伊人久久大香线蕉综合5g| 国产精品美女久久久免费| 午夜天堂精品久久久久| 久久久黄色大片| 性做久久久久久久久老女人| 久久国产美女免费观看精品| 狠狠色丁香婷婷综合久久来| 久久人人妻人人爽人人爽| 伊人久久精品无码av一区| 精品久久久久久久国产潘金莲| Xx性欧美肥妇精品久久久久久| 麻豆AV一区二区三区久久 | 精品久久久一二三区| 久久亚洲AV无码西西人体| 久久久精品久久久久特色影视| 99热成人精品免费久久| 久久无码人妻精品一区二区三区 | 色偷偷91久久综合噜噜噜噜| 久久av高潮av无码av喷吹|