Glibc記憶體管理--ptmalloc2原始碼分析
【轉】 http://mqzhuang.iteye.com/blog/1014287
Ptmalloc主要提供以下幾個配置選項用於調優,這些選項可以通過mallopt()進行設定:
1. M_MXFAST
M_MXFAST用於設定fast bins中儲存的chunk的最大大小,預設值為64B,fast bins中儲存的chunk在一段時間內不會被合併,分配小物件時可以首先查詢fast bins,如果fast bins找到了所需大小的chunk,就直接返回該chunk,大大提高小物件的分配速度,但這個值設定得過大,會導致大量記憶體碎片,並且會導致ptmalloc快取了大量空閒記憶體,去不能歸還給作業系統,導致記憶體暴增。
M_MXFAST的最大值為80B,不能設定比80B更大的值,因為設定為更大的值並不能提高分配的速度。Fast bins是為需要分配許多小物件的程式設計的,比如需要分配許多小struct,小物件,小的string等等。
如果設定該選項為0,就會不使用fast bins。
2. M_TRIM_THRESHOLD
M_TRIM_THRESHOLD用於設定mmap收縮閾值,預設值為128KB。自動收縮只會在free時才發生,如果當前free的chunk大小加上前後能合併chunk的大小大於64KB,並且top chunk的大小達到mmap收縮閾值,對於主分配區,呼叫malloc_trim()返回一部分記憶體給作業系統,對於非主分配區,呼叫heap_trim()返回一部分記憶體給作業系統,在發生記憶體收縮時,還是從新設定mmap分配閾值和mmap收縮閾值。
這個選項一般與M_MMAP_THRESHOLD選項一起使用,M_MMAP_THRESHOLD用於設定mmap分配閾值,對於長時間執行的程式,需要對這兩個選項進行調優,儘量保證在ptmalloc中快取的空閒chunk能夠得到重用,儘量少用mmap分配臨時用的記憶體。不停地使用系統呼叫mmap分配記憶體,然後很快又free掉該記憶體,這樣是很浪費系統資源的,並且這樣分配的記憶體的速度比從ptmalloc的空閒chunk中分配記憶體慢得多,由於需要頁對齊導致空間利用率降低,並且作業系統呼叫mmap()分配記憶體是序列的,在發生缺頁異常時載入新的物理頁,需要對新的物理頁做清0操作,大大影響效率。
M_TRIM_THRESHOLD的值必須設定為頁大小對齊,設定為-1會關閉記憶體收縮設定。
注意:試圖在程式開始執行時分配一塊大記憶體,並馬上釋放掉,以期望來觸發記憶體收縮,這是不可能的,因為該記憶體馬上就返回給作業系統了。
3. M_MMAP_THRESHOLD
M_MMAP_THRESHOLD用於設定mmap分配閾值,預設值為128KB,ptmalloc預設開啟動態調整mmap分配閾值和mmap收縮閾值。
當用戶需要分配的記憶體大於mmap分配閾值,ptmalloc的malloc()函式其實相當於mmap()的簡單封裝,free函式相當於munmap()的簡單封裝。相當於直接通過系統呼叫分配記憶體,回收的記憶體就直接返回給作業系統了。因為這些大塊記憶體不能被ptmalloc快取管理,不能重用,所以ptmalloc也只有在萬不得已的情況下才使用該方式分配記憶體。
但使用mmap分配有如下的好處:
l Mmap的空間可以獨立從系統中分配和釋放的系統,對於長時間執行的程式,申請長生命週期的大記憶體塊就很適合有這種方式。
l Mmap的空間不會被ptmalloc鎖在快取的chunk中,不會導致ptmalloc記憶體暴增的問題。
l 對有些系統的虛擬地址空間存在洞,只能用mmap()進行分配記憶體,sbrk()不能執行。
使用mmap分配記憶體的缺點:
l 該記憶體不能被ptmalloc回收再利用。
l 會導致更多的記憶體浪費,因為mmap需要按頁對齊。
l 它的分配效率跟作業系統提供的mmap()函式的效率密切相關,Linux系統強制把匿名mmap的記憶體物理頁清0是很低效的。
所以用mmap來分配長生命週期的大記憶體塊就是最好的選擇,其他情況下都不太高效。
4. M_MMAP_MAX
M_MMAP_MAX用於設定程序中用mmap分配的記憶體塊的最大限制,預設值為64K,因為有些系統用mmap分配的記憶體塊太多會導致系統的效能下降。
如果將M_MMAP_MAX設定為0,ptmalloc將不會使用mmap分配大塊記憶體。
Ptmalloc為優化鎖的競爭開銷,做了PER_THREAD的優化,也提供了兩個選項,M_ARENA_TEST和M_ARENA_MAX,由於PER_THREAD的優化預設沒有開啟,這裡暫不對這兩個選項做介紹。
另外,ptmalloc沒有提供關閉mmap分配閾值動態調整機制的選項,mmap分配閾值動態調整時預設開啟的,如果要關閉mmap分配閾值動態調整機制,可以設定M_TRIM_THRESHOLD,M_MMAP_THRESHOLD,M_TOP_PAD和M_MMAP_MAX中的任意一個。但是強烈建議不要關閉該機制,該機制保證了ptmalloc儘量重用快取中的空閒記憶體,不用每次對相對大一些的記憶體使用系統呼叫mmap去分配記憶體。