tcmalloc的工作原理

myownstars發表於2015-03-08

Tcmalloc優勢

1 速度快

ptmalloc在一臺2.8GHz的P4機器上(對於小物件)執行一次malloc及free大約需要300納秒。而TCMalloc的版本同樣的操作大約只需要50納秒。

2 降低了鎖爭用

TCMalloc減少了多執行緒程式中的鎖爭用情況。對於小物件,幾乎已經達到了零爭用。對於大物件,TCMalloc嘗試使用粒度較好和有效的自旋鎖。

3 節省記憶體

分配N個8位元組物件使用大約8N * 1.01位元組的空間。而ptmalloc2中每個物件都使用了一個四位元組的頭。

儘管ptmalloc2也實現了per-thread快取,,第一個執行緒申請的記憶體,釋放的時候還是必須放到第一個執行緒池中(不可移動),這樣可能導致大量記憶體浪費。

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.

tcmalloc跨執行緒歸還記憶體,是因為所有執行緒公用了底層的一個分配器?,所以跨執行緒歸還是無需加鎖的。

 

 

Tcmalloc概述

tcmalloc將記憶體請求分為兩類,大物件請求和小物件請求,大物件為>=32K的物件。

tcmalloc會為每個執行緒分配本地快取,小物件請求可以直接從本地快取獲取,如果沒有空閒記憶體,則從central heap中一次性獲取一連串小物件。

tcmalloc對於小記憶體,按8的整數次倍分配,對於大記憶體,按4K的整數次倍分配。

當某個執行緒快取中所有物件的總大小超過2MB的時候,會進行垃圾收集。垃圾收集閾值會自動根據執行緒數量的增加而減少,這樣就不會因為程式有大量執行緒而過度浪費記憶體。

 

 

使用

要使用TCMalloc,只要將tcmalloc透過“-ltcmalloc”連結器標誌接入你的應用即可。

也可以透過LD_PRELOAD動態載入:$ LD_PRELOAD=”/usr/lib/libtcmalloc.so”

 

To use TCmalloc, just link tcmalloc into your application via the "-ltcmalloc" linker flag.

You can use tcmalloc in applications you didn't compile yourself, by using LD_PRELOAD:$ LD_PRELOAD="/usr/lib/libtcmalloc.so"

LD_PRELOAD is tricky, and we don't necessarily recommend this mode of usage.

 

Mysql要使用tcmalloc,可以把tcmalloc動態庫加到mysqld_safe中啟動;

也可也靜態編譯,要依次編譯libunwind,tcmalloc,然後編譯mysql,configure中加入–with-mysqld-ldflags=-ltcmalloc選項,具體可參照

http://www.itpub.net/thread-1363139-1-1.html#

 

 

 

申請記憶體

1. 首先根據申請空間的大小從當前執行緒的可用記憶體塊裡面找(每個程式維護一組連結串列,每個連結串列代表一定大小的可用空間)

2. 如果step 1沒有找到,則到central list裡面查詢(central list跟執行緒各自維護的list結構很像,為不同的size各自維護一組可用空間列表)

3. 如果step 2 central list也沒有找到,則計算分配size個位元組需要分配多少page(變數:class_to_pages)

4. 根據pagemap查詢page對應的可用的span列表,如果找到了,則直接返回span,central list會將該span切割成合適的大小放入對應的列表中,然後交給thread cache

5. 如果step 4沒有找到可用的span,則向OS直接申請,然後步驟同step 4。

注意的是tcmalloc向系統申請空間有三種方式:sbrk,mmap,/dev/mem檔案,預設是三種都try的,一種不行換另外一種。

注:大物件直接使用頁級分配器(一個頁是一個4K的對齊記憶體區域)從中央堆直接分配。

 

 

執行緒釋放資源:

1. 釋放某個object

2. 找到該object所在的span

3. 如果該span中所有object都被釋放,則釋放該span到對應的可用列表,在釋放的過程中,嘗試將該span跟左右spans merge成更大的span

4. 如果當前thread cache的free 空間大於指定預置,歸還部分空間給central list

5. central list也會試圖透過釋放可用span列表的最後幾個span來將不用的空間歸還給OS

tcmalloc向OS申請/釋放資源是以span為單位的。

 

 

參考連結

http://www.cnblogs.com/raymondshiquan/archive/2011/06/25/tcmalloc_configuration_analysis.html

http://www.cppblog.com/feixuwu/archive/2010/07/10/119980.html

 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/15480802/viewspace-1452219/,如需轉載,請註明出處,否則將追究法律責任。