glibc 內(nèi)存分配總結(jié)

1审残、下載和編譯

源碼下載:https://www.gnu.org/software/libc/

下載后解壓:tar zxvf glibc-2.23.tar.gz?

(原來這里下載了glibc-2.2.3.tar.gz万搔,一個符號點之差歌憨,導(dǎo)致編譯了半天不成功,各種錯誤)

$ tar zxvf glibc-2.23.tar.gz?

$ mkdir?glibc-build bin

設(shè)置環(huán)境變量bashrc

?cat bashrc?

export PATH=$PATH:/home/xxxx/mini_ctc_3.3/toolchain/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/

export PATH=$PATH:/home/xxxx/yodaos/openwrt/staging_dir/toolchain-arm_cortex-a7+neon_gcc-5.3.0_glibc-2.22_eabi/bin/

export CROSS_COMPILE=aarch64-linux-gnu-

export STAGING_DIR=/home/chenguolong/yodaos/openwrt/staging_dir/target-arm_cortex-a7+neon_glibc-2.22_eabi/

#export CROSS_COMPILE=arm-openwrt-linux-gnueabi-

export CC=${CROSS_COMPILE}gcc

export CPP=${CROSS_COMPILE}cppc

export CXX=${CROSS_COMPILE}g++

export LD=${CROSS_COMPILE}ld

export AR=${CROSS_COMPILE}ar

export STRIP=${CROSS_COMPILE}strip

export CFLAGS="-Wno-error=implicit-function-declaration -Wno-error=parentheses -O2"

export CMAKE_C_COMPILER=${CROSS_COMPILE}gcc

$ source bashrc

開始編譯

$ cd?glibc-build

$/home/xxxx/tmp/tools/glibc-2.23/configure --prefix=/home/chenguolong/tmp/tools/bin/ --host=aarch64-linux-gnu --disable-multilib libc_cv_forced_unwind=yes libc_cv_ssp=no libc_cv_ssp_strong=no

如果需要靜態(tài)編譯

$ ./configure CFLAGS="-static" ....

$ make LDFLAGS="-all-static"

其實編譯開源軟件都一樣惶翻,--prefix即為install目錄蝶溶,--host為編譯程序的二進(jìn)制文件執(zhí)行的主機(jī)

build:執(zhí)行代碼編譯的主機(jī),正常的話就是你的主機(jī)系統(tǒng)俱济。這個參數(shù)一般由config.guess來猜就可以。當(dāng)然自己指定也可以钙勃。

host:編譯出來的二進(jìn)制程序所執(zhí)行的主機(jī)蛛碌,因為絕大多數(shù)是如果本機(jī)編譯,本機(jī)執(zhí)行辖源。所以這個值就等于build左医。只有交叉編譯的時候(也就是本機(jī)編譯,其他系統(tǒng)機(jī)器執(zhí)行)才會build和host不同同木。用host指定運行主機(jī)。

target:這個選項只有在建立交叉編譯環(huán)境的時候用到跛十,正常編譯和交叉編譯都不會用到彤路。他用build主機(jī)上的編譯器,編譯一個新的編譯器(binutils, gcc,gdb等)芥映,這個新的編譯器將來編譯出來的其他程序?qū)⑦\行在target指定的系統(tǒng)上洲尊。

$ make -j32 && make install

2、Glibc即ptmalloc內(nèi)存管理設(shè)計假設(shè)

Ptmalloc 在設(shè)計時折中了高效率奈偏,高空間利用率坞嘀,高可用性等設(shè)計目標(biāo)。在其實現(xiàn)代碼中惊来,隱藏著內(nèi)存管理中的一些設(shè)計假設(shè)丽涩,由于某些設(shè)計假設(shè),導(dǎo)致了在某些情況下 ptmalloc 的行為很詭異。這些設(shè)計假設(shè)包括:

1. 具有長生命周期的大內(nèi)存分配使用 mmap矢渊。

2. 特別大的內(nèi)存分配總是使用 mmap继准。

3. 具有短生命周期的內(nèi)存分配使用 brk,因為用 mmap 映射匿名頁矮男,當(dāng)發(fā)生缺頁異常時移必,linux 內(nèi)核為缺頁分配一個新物理頁,并將該物理頁清 0毡鉴,一個 mmap 的內(nèi)存塊需要映射多個物理頁崔泵,導(dǎo)致多次清 0 操作,很浪費系統(tǒng)資源猪瞬,所以引入了 mmap分配閾值動態(tài)調(diào)整機(jī)制憎瘸,保證在必要的情況下才使用 mmap 分配內(nèi)存。

4. 盡量只緩存臨時使用的空閑小內(nèi)存塊撑螺,對大內(nèi)存塊或是長生命周期的大內(nèi)存塊在釋放時都直接歸還給操作系統(tǒng)含思。

5. 對空閑的小內(nèi)存塊只會在 malloc 和 free 的時候進(jìn)行合并,free 時空閑內(nèi)存塊可能放入 pool 中甘晤,不一定歸還給操作系統(tǒng)含潘。

6. 收縮堆的條件是當(dāng)前 free 的塊大小加上前后能合并 chunk 的大小大于 64KB、线婚,并且堆頂?shù)拇笮∵_(dá)到閾值遏弱,才有可能收縮堆,把堆最頂端的空閑內(nèi)存返回給操作系統(tǒng)塞弊。

7. 需要保持長期存儲的程序不適合用 ptmalloc 來管理內(nèi)存漱逸。

8. 為了支持多線程,多個線程可以從同一個分配區(qū)(arena)中分配內(nèi)存游沿,ptmalloc假設(shè)線程 A 釋放掉一塊內(nèi)存后饰抒,線程 B 會申請類似大小的內(nèi)存,但是 A 釋放的內(nèi)存跟 B 需要的內(nèi)存不一定完全相等诀黍,可能有一個小的誤差袋坑,就需要不停地對內(nèi)存塊作切割和合并,這個過程中可能產(chǎn)生內(nèi)存碎片眯勾。

總結(jié):

大塊內(nèi)存用mmap枣宫,耗時耗cpu

小塊內(nèi)存用malloc(brk),申請內(nèi)存時并非立即真申請吃环,釋放時并非真釋放

3也颤、GLIBC 重要結(jié)構(gòu)體和函數(shù)

chunk:

使用中chunk
空閑chunk

bins

fast bins 快速查找的chunk

unsort bin 釋放后規(guī)整

top chunk?

Main_arena??主分配區(qū),有且只有一個

non_main_arena 非主分配區(qū)郁轻,多個翅娶,多線程競爭使用

引用東東圖,glibc重要結(jié)構(gòu)圖

4、glibc 內(nèi)存暴增原因

1故觅、后分配的內(nèi)存先釋放厂庇,因為 ptmalloc 收縮內(nèi)存是從 top chunk 開始,如果與 top chunk 相

鄰的 chunk 不能釋放输吏,top chunk 以下的 chunk 都無法釋放权旷。

2. Ptmalloc 不適合用于管理長生命周期的內(nèi)存,特別是持續(xù)不定期分配和釋放長生命周期

的內(nèi)存贯溅,這將導(dǎo)致 ptmalloc 內(nèi)存暴增拄氯。如果要用 ptmalloc 分配長周期內(nèi)存,在 32 位系

統(tǒng)上它浅,分配的內(nèi)存塊最好大于 1MB译柏,64 位系統(tǒng)上,分配的內(nèi)存塊大小大于 32MB姐霍。這是

由于 ptmalloc 默認(rèn)開啟 mmap 分配閾值動態(tài)調(diào)整功能鄙麦,1MB 是 32 位系統(tǒng) mmap 分配閾

值的最大值,32MB 是 64 位系統(tǒng) mmap 分配閾值的最大值镊折,這樣可以保證 ptmalloc 分配

的內(nèi)存一定是從 mmap 映射區(qū)域分配的胯府,當(dāng) free 時,ptmalloc 會直接把該內(nèi)存返回給操

作系統(tǒng)恨胚,避免了被 ptmalloc 緩存骂因。

3. 不要關(guān)閉 ptmalloc 的 mmap 分配閾值動態(tài)調(diào)整機(jī)制,因為這種機(jī)制保證了短生命周期的

內(nèi)存分配盡量從 ptmalloc 緩存的內(nèi)存 chunk 中分配赃泡,更高效寒波,浪費更少的內(nèi)存。如果關(guān)

閉了該機(jī)制升熊,對大于 128KB 的內(nèi)存分配就會使用系統(tǒng)調(diào)用 mmap 向操作系統(tǒng)分配內(nèi)存俄烁,

使用系統(tǒng)調(diào)用分配內(nèi)存一般會比從 ptmalloc 緩存的 chunk 中分配內(nèi)存慢,特別是在多線

程同時分配大內(nèi)存塊時级野,操作系統(tǒng)會串行調(diào)用 mmap()页屠,并為發(fā)生缺頁異常的頁加載新

物理頁時,默認(rèn)強(qiáng)制清 0勺阐。頻繁使用 mmap 向操作系統(tǒng)分配內(nèi)存是相當(dāng)?shù)托У摹J褂?/p>

mmap 分配的內(nèi)存只適合長生命周期的大內(nèi)存塊矛双。

4. 多線程分階段執(zhí)行的程序不適合用 ptmalloc渊抽,這種程序的內(nèi)存更適合用內(nèi)存池管理,就

像 Appach 那樣议忽,每個連接請求處理分為多個階段懒闷,每個階段都有自己的內(nèi)存池,每個

階段完成后,將相關(guān)的內(nèi)存就返回給相關(guān)的內(nèi)存池愤估。Google 的許多應(yīng)用也是分階段執(zhí)行

的帮辟,他們在使用 ptmalloc 也遇到了內(nèi)存暴增的相關(guān)問題,于是他們實現(xiàn)了 TCMalloc 來代

替 ptmalloc玩焰,TCMalloc 具有內(nèi)存池的優(yōu)點由驹,又有垃圾回收的機(jī)制,并最大限度優(yōu)化了鎖

的爭用昔园,并且空間利用率也高于 ptmalloc蔓榄。Ptmalloc 假設(shè)了線程 A 釋放的內(nèi)存塊能在線

程 B 中得到重用,但 B 不一定會分配和 A 線程同樣大小的內(nèi)存塊默刚,于是就需要不斷地做

切割和合并甥郑,可能導(dǎo)致內(nèi)存碎片。

5. 盡量減少程序的線程數(shù)量和避免頻繁分配/釋放內(nèi)存荤西,Ptmalloc 在多線程競爭激烈的情況

下澜搅,首先查看線程私有變量是否存在分配區(qū),如果存在則嘗試加鎖邪锌,如果加鎖不成功會

嘗試其它分配區(qū)勉躺,如果所有的分配區(qū)的鎖都被占用著,就會增加一個非主分配區(qū)供當(dāng)前

線程使用秃流。由于在多個線程的私有變量中可能會保存同一個分配區(qū)赂蕴,所以當(dāng)線程較多時,

加鎖的代價就會上升舶胀,ptmalloc 分配和回收內(nèi)存都要對分配區(qū)加鎖概说,從而導(dǎo)致了多線程

競爭環(huán)境下 ptmalloc 的效率降低。

6. 防止內(nèi)存泄露嚣伐,ptmalloc 對內(nèi)存泄露是相當(dāng)敏感的糖赔,根據(jù)它的內(nèi)存收縮機(jī)制,如果與 top

chunk 相鄰的那個 chunk 沒有回收轩端,將導(dǎo)致 top chunk 一下很多的空閑內(nèi)存都無法返回給

操作系統(tǒng)放典。

7. 防止程序分配過多內(nèi)存,或是由于 Glibc 內(nèi)存暴增基茵,導(dǎo)致系統(tǒng)內(nèi)存耗盡奋构,程序因 OOM 被

系 統(tǒng) 殺 掉 。 預(yù) 估 程 序 可 以 使 用 的 最 大 物 理 內(nèi) 存 大 小 拱层, 配 置 系 統(tǒng) 的

/proc/sys/vm/overcommit_memory弥臼,/proc/sys/vm/overcommit_ratio,以及使用 ulimt –v

限制程序能使用虛擬內(nèi)存空間大小根灯,防止程序因 OOM 被殺掉径缅。

5掺栅、GLBIC 申請或者收縮(釋放)域值調(diào)整

1. M_MXFAST

M_MXFAST 用于設(shè)置 fast bins 中保存的 chunk 的最大大小,默認(rèn)值為 64B纳猪,fast bins 中

保存的 chunk 在一段時間內(nèi)不會被合并氧卧,分配小對象時可以首先查找 fast bins,如果 fast bins

找到了所需大小的 chunk氏堤,就直接返回該 chunk沙绝,大大提高小對象的分配速度,但這個值設(shè)

置得過大丽猬,會導(dǎo)致大量內(nèi)存碎片宿饱,并且會導(dǎo)致 ptmalloc 緩存了大量空閑內(nèi)存,去不能歸還給

操作系統(tǒng)脚祟,導(dǎo)致內(nèi)存暴增谬以。

2. M_TRIM_THRESHOLD

M_TRIM_THRESHOLD 用于設(shè)置 mmap 收縮閾值,默認(rèn)值為 128KB由桌。自動收縮只會在 free

時才發(fā)生为黎,如果當(dāng)前 free 的 chunk 大小加上前后能合并 chunk 的大小大于 64KB,并且 top

chunk 的大小達(dá)到 mmap 收縮閾值行您,對于主分配區(qū)铭乾,調(diào)用 malloc_trim()返回一部分內(nèi)存給操

作系統(tǒng),對于非主分配區(qū)娃循,調(diào)用 heap_trim()返回一部分內(nèi)存給操作系統(tǒng)炕檩,在發(fā)生內(nèi)存收縮

時,還是從新設(shè)置 mmap 分配閾值和 mmap 收縮閾值捌斧。

3. M_MMAP_THRESHOLD

M_MMAP_THRESHOLD 用于設(shè)置 mmap 分配閾值笛质,默認(rèn)值為 128KB,ptmalloc 默認(rèn)開啟

動態(tài)調(diào)整 mmap 分配閾值和 mmap 收縮閾值捞蚂。

4. M_MMAP_MAX

M_MMAP_MAX 用于設(shè)置進(jìn)程中用 mmap 分配的內(nèi)存塊的最大限制妇押,默認(rèn)值為 64K,因

為有些系統(tǒng)用 mmap 分配的內(nèi)存塊太多會導(dǎo)致系統(tǒng)的性能下降姓迅。

代碼設(shè)置:

include <malloc.h>

mallopt(M_TRIM_THRESHOLD, 32 * 1024);

mallopt(M_MMAP_THRESHOLD, 64 * 1024);

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末敲霍,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子丁存,更是在濱河造成了極大的恐慌肩杈,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,423評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件解寝,死亡現(xiàn)場離奇詭異扩然,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)编丘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,147評論 2 385
  • 文/潘曉璐 我一進(jìn)店門与学,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人嘉抓,你說我怎么就攤上這事索守。” “怎么了抑片?”我有些...
    開封第一講書人閱讀 157,019評論 0 348
  • 文/不壞的土叔 我叫張陵卵佛,是天一觀的道長。 經(jīng)常有香客問我敞斋,道長截汪,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,443評論 1 283
  • 正文 為了忘掉前任植捎,我火速辦了婚禮衙解,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘焰枢。我一直安慰自己蚓峦,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,535評論 6 385
  • 文/花漫 我一把揭開白布济锄。 她就那樣靜靜地躺著暑椰,像睡著了一般。 火紅的嫁衣襯著肌膚如雪荐绝。 梳的紋絲不亂的頭發(fā)上一汽,一...
    開封第一講書人閱讀 49,798評論 1 290
  • 那天,我揣著相機(jī)與錄音低滩,去河邊找鬼召夹。 笑死,一個胖子當(dāng)著我的面吹牛委造,可吹牛的內(nèi)容都是我干的戳鹅。 我是一名探鬼主播,決...
    沈念sama閱讀 38,941評論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼昏兆,長吁一口氣:“原來是場噩夢啊……” “哼枫虏!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起爬虱,我...
    開封第一講書人閱讀 37,704評論 0 266
  • 序言:老撾萬榮一對情侶失蹤隶债,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后跑筝,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體死讹,經(jīng)...
    沈念sama閱讀 44,152評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,494評論 2 327
  • 正文 我和宋清朗相戀三年曲梗,在試婚紗的時候發(fā)現(xiàn)自己被綠了赞警。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片妓忍。...
    茶點故事閱讀 38,629評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖愧旦,靈堂內(nèi)的尸體忽然破棺而出世剖,到底是詐尸還是另有隱情,我是刑警寧澤笤虫,帶...
    沈念sama閱讀 34,295評論 4 329
  • 正文 年R本政府宣布旁瘫,位于F島的核電站,受9級特大地震影響琼蚯,放射性物質(zhì)發(fā)生泄漏酬凳。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,901評論 3 313
  • 文/蒙蒙 一遭庶、第九天 我趴在偏房一處隱蔽的房頂上張望宁仔。 院中可真熱鬧,春花似錦峦睡、人聲如沸台诗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拉队。三九已至,卻和暖如春阻逮,著一層夾襖步出監(jiān)牢的瞬間粱快,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,978評論 1 266
  • 我被黑心中介騙來泰國打工叔扼, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留事哭,地道東北人。 一個月前我還...
    沈念sama閱讀 46,333評論 2 360
  • 正文 我出身青樓瓜富,卻偏偏與公主長得像鳍咱,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子与柑,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,499評論 2 348

推薦閱讀更多精彩內(nèi)容