日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

ptmalloc,tcmalloc和jemalloc内存分配策略研究

發(fā)布時(shí)間:2023/12/20 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ptmalloc,tcmalloc和jemalloc内存分配策略研究 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

轉(zhuǎn)載:https://cloud.tencent.com/developer/article/1173720

?

操作系統(tǒng)內(nèi)存布局

各種malloc的內(nèi)存分配管理方式離不開(kāi)操作系統(tǒng)的內(nèi)存布局策略。

32位經(jīng)典內(nèi)存布局

32位系統(tǒng)下經(jīng)典內(nèi)存布局如上,程序起始的1GB地址為內(nèi)核空間,接下來(lái)是向下增長(zhǎng)的棧空間和由0x40000000向上增長(zhǎng)的mmap地址。而堆地址是從底部開(kāi)始,去除ELF、數(shù)據(jù)段、代碼段、常量段之后的地址并向上增長(zhǎng)。但是這種布局有幾個(gè)問(wèn)題,首先是容易遭受溢出攻擊;其次是,堆地址空間只有不到1G有木有?如果mmap內(nèi)存比較少地址很浪費(fèi)有木有?所以后來(lái)就有了另一種內(nèi)存布局。

32位默認(rèn)內(nèi)存布局

這幅圖描述地比較清楚也比較完整。首先是加入了幾種Random offset隨機(jī)偏移,導(dǎo)致內(nèi)存溢出攻擊不那么容易了,其次是堆仍然向上,但是mmap向下增長(zhǎng)。但是這樣的話棧空間就不是動(dòng)態(tài)增長(zhǎng)的了,所以現(xiàn)在的操作系統(tǒng)都有棧大小限制來(lái)著(Windows好像默認(rèn)是2MB對(duì)吧?Linux可以u(píng)limit –s查看)。這種內(nèi)存布局地址利用度比較高。

64位內(nèi)存布局

64位系統(tǒng)的尋址空間比較大,所以仍然沿用了32位的經(jīng)典布局,但是加上了隨機(jī)的mmap起始地址,以防止溢出攻擊。反正一時(shí)半會(huì)是用不了這么大的內(nèi)存地址了,所以至少N多年不會(huì)變了(話說(shuō)要生產(chǎn)出40TB+的內(nèi)存條,把堆內(nèi)存地址用光,一時(shí)半會(huì)也搞不定吧)。

總結(jié)

縱觀各種內(nèi)存布局,對(duì)于大內(nèi)存各種malloc基本上都是直接mmap的。而對(duì)于小數(shù)據(jù),則通過(guò)向操作系統(tǒng)申請(qǐng)擴(kuò)大堆頂,這時(shí)候操作系統(tǒng)會(huì)把需要的內(nèi)存分頁(yè)映射過(guò)來(lái),然后再由這些malloc管理這些堆內(nèi)存塊,減少系統(tǒng)調(diào)用。而在free內(nèi)存的時(shí)候,不同的malloc有不同的策略,不一定會(huì)把內(nèi)存真正地還給系統(tǒng),所以很多時(shí)候,如果訪問(wèn)了free掉的內(nèi)存,并不會(huì)立即Run Time Error,只有訪問(wèn)的地址沒(méi)有對(duì)應(yīng)的內(nèi)存分頁(yè),才會(huì)崩掉。

Ptmalloc

Ptmalloc采用主-從分配區(qū)的模式,當(dāng)一個(gè)線程需要分配資源的時(shí)候,從鏈表中找到一個(gè)沒(méi)加鎖的分配區(qū),在進(jìn)行內(nèi)存分配。

小內(nèi)存分配

在ptmalloc內(nèi)部,內(nèi)存塊采用chunk管理,并且將大小相似的chunk用鏈表管理,一個(gè)鏈表被稱為一個(gè)bin。前64個(gè)bin里,相鄰的bin內(nèi)的chunk大小相差8字節(jié),稱為small bin,后面的是large bin,large bin里的chunk按先大小,再最近使用的順序排列,每次分配都找一個(gè)最小的能夠使用的chunk。

Chunk的結(jié)構(gòu)如上所示,A位表示是不是在主分配區(qū)M表示是不是mmap出來(lái)滴P表示上一個(gè)內(nèi)存緊鄰的chunk是否在使用,如果沒(méi)在使用,則size of previous chunk是上一個(gè)chunk的大小,否則無(wú)意義(而且被用作被分配出去的內(nèi)存了),正式根據(jù)P標(biāo)記位和size of previous chunk在free內(nèi)存塊的時(shí)候來(lái)進(jìn)行chunk合并的。當(dāng)然,如果chunk空閑,mem里還記錄了一些指針用于索引臨近大小的chunk的,實(shí)現(xiàn)原理就不復(fù)述了,知道大致作用就行。

在free的時(shí)候,ptmalloc會(huì)檢查附近的chunk,并嘗試把連續(xù)空閑的chunk合并成一個(gè)大的chunk,放到unstored bin里。但是當(dāng)很小的chunk釋放的時(shí)候,ptmalloc會(huì)把它并入fast bin中。同樣,某些時(shí)候,fast bin里的連續(xù)內(nèi)存塊會(huì)被合并并加入到一個(gè)unsorted bin里,然后再才進(jìn)入普通bin里。所以malloc小內(nèi)存的時(shí)候,是先查找fast bin,再查找unsorted bin,最后查找普通的bin,如果unsorted bin里的chunk不合適,則會(huì)把它扔到bin里。

大內(nèi)存分配

Ptmalloc的分配的內(nèi)存頂部還有一個(gè)top chunk,如果前面的bin里的空閑chunk都不足以滿足需要,就是嘗試從top chunk里分配內(nèi)存。如果top chunk里也不夠,就要從操作系統(tǒng)里拿了。

還有就是特別大的內(nèi)存,會(huì)直接從系統(tǒng)mmap出來(lái),不受chunk管理,這樣的內(nèi)存在回收的時(shí)候也會(huì)munmap還給操作系統(tǒng)。

簡(jiǎn)而言之,就是:**

**小內(nèi)存: [獲取分配區(qū)(arena)并加鎖] -> fast bin -> unsorted bin -> small bin -> large bin -> top chunk -> 擴(kuò)展堆

大內(nèi)存: 直接mmap

總結(jié)

釋放的時(shí)候,幾乎是和分配反過(guò)來(lái),再加上可一些chunk合并和從一個(gè)bin轉(zhuǎn)移到另一個(gè)bin的操作。并且如果頂部有足夠大的空閑chunk,則收縮堆頂并還給操作系統(tǒng)。

介于此,對(duì)于ptmalloc的內(nèi)存分配使用有幾個(gè)注意事項(xiàng)

  • Ptmalloc默認(rèn)后分配內(nèi)存先釋放,因?yàn)閮?nèi)存回收是從top chunk開(kāi)始的。
  • 避免多線程頻繁分配和釋放內(nèi)存,會(huì)造成頻繁加解鎖。
  • 不要分配長(zhǎng)生命周期的內(nèi)存塊,容易造成內(nèi)碎片,影響內(nèi)存回收。
  • 總結(jié)

    以上是生活随笔為你收集整理的ptmalloc,tcmalloc和jemalloc内存分配策略研究的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。