內存池
應用層內存池 -> C 庫內存池
Google 的 TCMalloc(預分配內存更少的內存池) 和 FaceBook 的 JEMalloc
Linux 系統的默認 C 庫內存池 Ptmalloc2
當主進程下申請 1 字節的內存時,Ptmalloc2 會預分配 132K 字節的內存(Ptmalloc2 中叫 Main Arena),應用代碼再申請內存時,會從這已經申請到的 132KB 中繼續分配,當我們釋放這 1 字節時,Ptmalloc2 也不會把內存歸還給操作系統
多線程每個子線程預分配的內存是 64MB,子線程內存池最多只能到 8 倍的 CPU 核數(通過設置 MALLOC_ARENA_MAX 環境變量,可以限制線程內存池的最大數量)
TCMalloc 適用的場景,它對多線程下小內存的分配特別友好,當應用場景涉及大量的並發線程時,換成 TCMalloc 庫也更有優勢
每次分配內存,Ptmalloc2 一定要加鎖,才能解決共享資源的互斥問題。然而,加鎖的消耗並不小。如果你監控分配速度的話,會發現單線程服務調整為 100 個線程,Ptmalloc2 申請內存的速度會變慢 10 倍。TCMalloc 針對小內存做了很多優化,每個線程獨立分配內存,無須加鎖,所以速度更快
如果主要分配 256KB 以下的內存,特別是在多線程環境下,應當選擇 TCMalloc;否則應使用 Ptmalloc2,它的通用性更好。
由於每個線程都有獨立的棧,所以分配內存時不需要加鎖保護,而且棧上對象的尺寸在編譯階段就已經寫入可執行文件了,執行效率更高,缺點是生命周期和棧空間限制
Ptmalloc2 為子線程預分配了 64MB 內存池,雖然增大了內存消耗,但卻加快了分配速度,這就是以空間換時間的思想