【深入淺出Linux】關(guān)于mmap的解析

前言

看這篇文章之前需要知道一個(gè)概念

虛擬內(nèi)存系統(tǒng)通過(guò)將虛擬內(nèi)存分割為稱作虛擬頁(yè)(Virtual Page荸频,VP)大小固定的塊选泻,一般情況下窝稿,每個(gè)虛擬頁(yè)的大小默認(rèn)是4096字節(jié)祝闻。同樣的奕谭,物理內(nèi)存也被分割為物理頁(yè)(Physical Page,PP)贵涵,也為4096字節(jié)列肢。

一、mmap基本原理和分類

在LINUX中我們可以使用mmap用來(lái)在進(jìn)程虛擬內(nèi)存地址空間中分配地址空間独悴,創(chuàng)建和物理內(nèi)存的映射關(guān)系例书。

映射關(guān)系

映射關(guān)系可以分為兩種
1、文件映射
磁盤(pán)文件映射進(jìn)程的虛擬地址空間刻炒,使用文件內(nèi)容初始化物理內(nèi)存决采。
2、匿名映射
初始化全為0的內(nèi)存空間坟奥。

而對(duì)于映射關(guān)系是否共享又分為
1树瞭、私有映射(MAP_PRIVATE)
多進(jìn)程間數(shù)據(jù)共享,修改不反應(yīng)到磁盤(pán)實(shí)際文件爱谁,是一個(gè)copy-on-write(寫(xiě)時(shí)復(fù)制)的映射方式晒喷。
2、共享映射(MAP_SHARED)
多進(jìn)程間數(shù)據(jù)共享访敌,修改反應(yīng)到磁盤(pán)實(shí)際文件中凉敲。

因此總結(jié)起來(lái)有4種組合
1、私有文件映射
多個(gè)進(jìn)程使用同樣的物理內(nèi)存頁(yè)進(jìn)行初始化寺旺,但是各個(gè)進(jìn)程對(duì)內(nèi)存文件的修改不會(huì)共享爷抓,也不會(huì)反應(yīng)到物理文件中

2、私有匿名映射
mmap會(huì)創(chuàng)建一個(gè)新的映射阻塑,各個(gè)進(jìn)程不共享蓝撇,這種使用主要用于分配內(nèi)存(malloc分配大內(nèi)存會(huì)調(diào)用mmap)。
例如開(kāi)辟新進(jìn)程時(shí)陈莽,會(huì)為每個(gè)進(jìn)程分配虛擬的地址空間渤昌,這些虛擬地址映射的物理內(nèi)存空間各個(gè)進(jìn)程間讀的時(shí)候共享,寫(xiě)的時(shí)候會(huì)copy-on-write走搁。

3独柑、共享文件映射
多個(gè)進(jìn)程通過(guò)虛擬內(nèi)存技術(shù)共享同樣的物理內(nèi)存空間,對(duì)內(nèi)存文件 的修改會(huì)反應(yīng)到實(shí)際物理文件中私植,他也是進(jìn)程間通信(IPC)的一種機(jī)制忌栅。

4、共享匿名映射
這種機(jī)制在進(jìn)行fork的時(shí)候不會(huì)采用寫(xiě)時(shí)復(fù)制兵琳,父子進(jìn)程完全共享同樣的物理內(nèi)存頁(yè)狂秘,這也就實(shí)現(xiàn)了父子進(jìn)程通信(IPC).

這里值得注意的是,mmap只是在虛擬內(nèi)存分配了地址空間躯肌,只有在第一次訪問(wèn)虛擬內(nèi)存的時(shí)候才分配物理內(nèi)存者春。
在mmap之后,并沒(méi)有在將文件內(nèi)容加載到物理頁(yè)上清女,只上在虛擬內(nèi)存中分配了地址空間钱烟。當(dāng)進(jìn)程在訪問(wèn)這段地址時(shí),通過(guò)查找頁(yè)表嫡丙,發(fā)現(xiàn)虛擬內(nèi)存對(duì)應(yīng)的頁(yè)沒(méi)有在物理內(nèi)存中緩存拴袭,則產(chǎn)生"缺頁(yè)",由內(nèi)核的缺頁(yè)異常處理程序處理曙博,將文件對(duì)應(yīng)內(nèi)容拥刻,以頁(yè)為單位(4096)加載到物理內(nèi)存,注意是只加載缺頁(yè)父泳,但也會(huì)受操作系統(tǒng)一些調(diào)度策略影響般哼,加載的比所需的多。

二.mmap在write和read時(shí)會(huì)發(fā)生什么

1.write

  • 1.進(jìn)程(用戶態(tài))將需要寫(xiě)入的數(shù)據(jù)直接copy到對(duì)應(yīng)的mmap地址(內(nèi)存copy)
  • 2.若mmap地址未對(duì)應(yīng)物理內(nèi)存惠窄,則產(chǎn)生缺頁(yè)異常蒸眠,由內(nèi)核處理
  • 3.若已對(duì)應(yīng),則直接copy到對(duì)應(yīng)的物理內(nèi)存
  • 4.由操作系統(tǒng)調(diào)用杆融,將臟頁(yè)回寫(xiě)到磁盤(pán)(通常是異步的)

因?yàn)槲锢韮?nèi)存是有限的楞卡,mmap在寫(xiě)入數(shù)據(jù)超過(guò)物理內(nèi)存時(shí),操作系統(tǒng)會(huì)進(jìn)行頁(yè)置換脾歇,根據(jù)淘汰算法蒋腮,將需要淘汰的頁(yè)置換成所需的新頁(yè),所以mmap對(duì)應(yīng)的內(nèi)存是可以被淘汰的(若內(nèi)存頁(yè)是"臟"的介劫,則操作系統(tǒng)會(huì)先將數(shù)據(jù)回寫(xiě)磁盤(pán)再淘汰)徽惋。這樣,就算mmap的數(shù)據(jù)遠(yuǎn)大于物理內(nèi)存座韵,操作系統(tǒng)也能很好地處理险绘,不會(huì)產(chǎn)生功能上的問(wèn)題。

2.read

讀的過(guò)程對(duì)比

從圖中可以看出誉碴,mmap要比普通的read系統(tǒng)調(diào)用少了一次copy的過(guò)程宦棺。因?yàn)閞ead調(diào)用,進(jìn)程是無(wú)法直接訪問(wèn)kernel space的黔帕,所以在read系統(tǒng)調(diào)用返回前代咸,內(nèi)核需要將數(shù)據(jù)從內(nèi)核復(fù)制到進(jìn)程指定的buffer。但mmap之后成黄,進(jìn)程可以直接訪問(wèn)mmap的數(shù)據(jù)(page cache)呐芥。

三.性能分析

測(cè)試結(jié)果來(lái)源于:深入剖析mmap-從三個(gè)關(guān)鍵問(wèn)題說(shuō)起

1.讀性能分析
場(chǎng)景:對(duì)2G的文件進(jìn)行順序?qū)懭?/p>

每次寫(xiě)入大小 mmap 耗時(shí) write 耗時(shí)
100 bytes 2.84s 22.86s
512 bytes 2.51s 5.43s
1024 bytes 2.48s 3.48s
2048 bytes 2.47s 2.34s
4096 bytes 2.48s 1.74s
8192 bytes 2.45s 1.67s
10240 bytes 2.49s 1.65s

可以看到mmap在100byte寫(xiě)入時(shí)已經(jīng)基本達(dá)到最大寫(xiě)入性能逻杖,而write調(diào)用需要在4096(也就是一個(gè)page size)時(shí),才能達(dá)到最大寫(xiě)入性能思瘟。
從測(cè)試結(jié)果可以看出荸百,在寫(xiě)小數(shù)據(jù)時(shí),mmap會(huì)比write調(diào)用快滨攻,但在寫(xiě)大數(shù)據(jù)時(shí)够话,反而沒(méi)那么快。

2.寫(xiě)性能分析
場(chǎng)景:對(duì)2G的文件進(jìn)行順序讀裙馊啤(為了避免磁盤(pán)對(duì)測(cè)試的影響女嘲,2G文件都緩存在pagecache中)

每次讀取大小 mmap 耗時(shí) read 耗時(shí)
100 bytes 86.4ms 8100.9ms
512 bytes 16.14ms 1851.45ms
1024 bytes 8.11ms 992.71ms
2048 bytes 4.09ms 636.85ms
4096 bytes 2.07ms 558.10ms
8192 bytes 1.06ms 444.83ms
10240 bytes 867.88μs 475.28ms

由上可以看出,在read上面诞帐,mmap的性能還是非常好的欣尼。

四.總結(jié)

優(yōu)點(diǎn)如下:

1、對(duì)文件的讀取操作跨過(guò)了頁(yè)緩存景埃,減少了數(shù)據(jù)的拷貝次數(shù)媒至,用內(nèi)存讀寫(xiě)取代I/O讀寫(xiě),提高了文件讀取效率谷徙。

2拒啰、實(shí)現(xiàn)了用戶空間和內(nèi)核空間的高效交互方式。兩空間的各自修改操作可以直接反映在映射的區(qū)域內(nèi)完慧,從而被對(duì)方空間及時(shí)捕捉谋旦。

3、提供進(jìn)程間共享內(nèi)存及相互通信的方式屈尼。不管是父子進(jìn)程還是無(wú)親緣關(guān)系的進(jìn)程册着,都可以將自身用戶空間映射到同一個(gè)文件或匿名映射到同一片區(qū)域。從而通過(guò)各自對(duì)映射區(qū)域的改動(dòng)脾歧,達(dá)到進(jìn)程間通信和進(jìn)程間共享的目的甲捏。同時(shí),如果進(jìn)程A和進(jìn)程B都映射了區(qū)域C鞭执,當(dāng)A第一次讀取C時(shí)通過(guò)缺頁(yè)從磁盤(pán)復(fù)制文件頁(yè)到內(nèi)存中司顿;但當(dāng)B再讀C的相同頁(yè)面時(shí),雖然也會(huì)產(chǎn)生缺頁(yè)異常兄纺,但是不再需要從磁盤(pán)中復(fù)制文件過(guò)來(lái)大溜,而可直接使用已經(jīng)保存在內(nèi)存中的文件數(shù)據(jù)。

4估脆、可用于實(shí)現(xiàn)高效的大規(guī)模數(shù)據(jù)傳輸钦奋。內(nèi)存空間不足,是制約大數(shù)據(jù)操作的一個(gè)方面,解決方案往往是借助硬盤(pán)空間協(xié)助操作付材,補(bǔ)充內(nèi)存的不足朦拖。但是進(jìn)一步會(huì)造成大量的文件I/O操作,極大影響效率厌衔。這個(gè)問(wèn)題可以通過(guò)mmap映射很好的解決贞谓。換句話說(shuō),但凡是需要用磁盤(pán)空間代替內(nèi)存的時(shí)候葵诈,mmap都可以發(fā)揮其功效。

缺點(diǎn)如下:

1.文件如果很小祟同,是小于4096字節(jié)的作喘,比如10字節(jié),由于內(nèi)存的最小粒度是頁(yè)晕城,而進(jìn)程虛擬地址空間和內(nèi)存的映射也是以頁(yè)為單位泞坦。雖然被映射的文件只有10字節(jié),但是對(duì)應(yīng)到進(jìn)程虛擬地址區(qū)域的大小需要滿足整頁(yè)大小砖顷,因此mmap函數(shù)執(zhí)行后贰锁,實(shí)際映射到虛擬內(nèi)存區(qū)域的是4096個(gè)字節(jié),11~4096的字節(jié)部分用零填充滤蝠。因此如果連續(xù)mmap小文件豌熄,會(huì)浪費(fèi)內(nèi)存空間。

  1. 對(duì)變長(zhǎng)文件不適合物咳,文件無(wú)法完成拓展锣险,因?yàn)閙map到內(nèi)存的時(shí)候,你所能夠操作的范圍就確定了览闰。

3.如果更新文件的操作很多芯肤,會(huì)觸發(fā)大量的臟頁(yè)回寫(xiě)及由此引發(fā)的隨機(jī)IO上。所以在隨機(jī)寫(xiě)很多的情況下压鉴,mmap方式在效率上不一定會(huì)比帶緩沖區(qū)的一般寫(xiě)快崖咨。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市油吭,隨后出現(xiàn)的幾起案子击蹲,更是在濱河造成了極大的恐慌,老刑警劉巖上鞠,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件际邻,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡芍阎,警方通過(guò)查閱死者的電腦和手機(jī)世曾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人轮听,你說(shuō)我怎么就攤上這事骗露。” “怎么了血巍?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵萧锉,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我述寡,道長(zhǎng)柿隙,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任鲫凶,我火速辦了婚禮禀崖,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘螟炫。我一直安慰自己波附,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布昼钻。 她就那樣靜靜地躺著掸屡,像睡著了一般。 火紅的嫁衣襯著肌膚如雪然评。 梳的紋絲不亂的頭發(fā)上仅财,一...
    開(kāi)封第一講書(shū)人閱讀 49,031評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音碗淌,去河邊找鬼满着。 笑死,一個(gè)胖子當(dāng)著我的面吹牛贯莺,可吹牛的內(nèi)容都是我干的风喇。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼缕探,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼魂莫!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起爹耗,我...
    開(kāi)封第一講書(shū)人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤耙考,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后潭兽,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體倦始,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年山卦,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了鞋邑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖枚碗,靈堂內(nèi)的尸體忽然破棺而出逾一,到底是詐尸還是另有隱情,我是刑警寧澤肮雨,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布遵堵,位于F島的核電站,受9級(jí)特大地震影響怨规,放射性物質(zhì)發(fā)生泄漏陌宿。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一波丰、第九天 我趴在偏房一處隱蔽的房頂上張望限番。 院中可真熱鬧,春花似錦呀舔、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至珠插,卻和暖如春惧磺,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背捻撑。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工磨隘, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人顾患。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓番捂,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親江解。 傳聞我的和親對(duì)象是個(gè)殘疾皇子设预,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345