您好,登錄后才能下訂單哦!
這篇“Linux內(nèi)存布局是怎樣的”文章的知識點(diǎn)大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細(xì),步驟清晰,具有一定的借鑒價(jià)值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Linux內(nèi)存布局是怎樣的”文章吧。
我們先來看下Linux內(nèi)存布局:
在linux中,每一個(gè)進(jìn)程都被抽象為task_struct結(jié)構(gòu)體,稱為進(jìn)程描述符,存儲著進(jìn)程
各方面的信息;例如打開的文件,信號以及內(nèi)存等等;然后task_struct的一個(gè)屬性mm_struct管理著進(jìn)程的所有虛擬內(nèi)存,稱為內(nèi)存描述符。在mm_struct結(jié)構(gòu)體中,存儲著進(jìn)程各個(gè)內(nèi)存段的開始以及結(jié)尾,如上圖所示;這個(gè)進(jìn)程使用的物理內(nèi)存,即常駐內(nèi)存RSS頁數(shù),這個(gè)內(nèi)存使用的虛擬地址空間VSZ頁數(shù),還有這個(gè)進(jìn)程虛擬內(nèi)存區(qū)域集合和頁表。
從上面這個(gè)圖可以看出,進(jìn)程是有代碼段Text segment,數(shù)據(jù)段(已初始化的全局,靜態(tài)變量),BSS段(未初始化的全局,靜態(tài)變量),堆,內(nèi)存映射區(qū)以及棧;
每一塊虛擬內(nèi)存區(qū)(VMA)都是由一塊連續(xù)的虛擬地址組成,這些地址從不覆蓋。一個(gè)vm_area_struct實(shí)例描述了一塊內(nèi)存區(qū)域,包括這塊內(nèi)存區(qū)域的開始以及結(jié)尾地址;flags標(biāo)志決定了這塊內(nèi)存的訪問權(quán)限和行為;vm_file決定這塊內(nèi)存是由哪個(gè)文件映射的,如果沒有文件映射,則這塊內(nèi)存為匿名的(anonymous)。上述圖中提到的每個(gè)內(nèi)存段,都對應(yīng)于一個(gè)vm_area_struct結(jié)構(gòu)。如下圖所示
上圖即為/bin/gonzo進(jìn)程的內(nèi)存布局。程序的二進(jìn)制文件映射到代碼段和數(shù)據(jù)段,代碼段為只讀只執(zhí)行,不可更改;全局以及靜態(tài)的未初始化的變量映射到BSS段,為匿名映射,堆和棧也是匿名映射,因?yàn)闆]有相應(yīng)的文件映射;內(nèi)存映射區(qū)可以映射共享庫,映射文件以及匿名映射,所以這塊內(nèi)存段可以是文件映射也可以是匿名映射。而且不同的文件,映射到不同的vm_area_struct區(qū)。
這些vm_area_struct集合存儲在mm_struct中的一個(gè)單向鏈表和紅黑樹中;當(dāng)輸出/proc/pid/maps文件時(shí),只需要遍歷這個(gè)鏈表即可。紅黑樹主要是為了快速定位到某一個(gè)內(nèi)存塊,紅黑樹的根存儲在mm_rb域。
之前介紹過,線性地址需要通過頁表才能轉(zhuǎn)換為物理地址。每個(gè)進(jìn)程的內(nèi)存描述符也保存了這個(gè)進(jìn)程頁表指針pgd,每一塊虛擬內(nèi)存頁都和頁表的某一項(xiàng)對應(yīng)。
虛擬內(nèi)存是不存儲任何數(shù)據(jù)的,它只是將地址空間映射到物理內(nèi)存。物理內(nèi)存有內(nèi)核伙伴系統(tǒng)分配,如果一塊物理內(nèi)存沒有被映射,就可以被伙伴系統(tǒng)分配給虛擬內(nèi)存。剛分配的物理內(nèi)存葉框可能是匿名的,存儲進(jìn)程數(shù)據(jù),也可能是也緩存,存儲文件或塊設(shè)備的數(shù)據(jù)。一塊虛擬內(nèi)存vm_area_struct塊是由連續(xù)的虛擬內(nèi)存頁組成的,而這些虛擬內(nèi)存塊映射的物理內(nèi)存卻不一定連續(xù),如下圖所示:
如上圖所示,有三個(gè)頁映射到物理內(nèi)存,還有兩個(gè)頁沒有映射,所以常駐內(nèi)存RSS為12kb,而虛擬內(nèi)存大小為20kb。對于有映射到物理內(nèi)存的三個(gè)頁的頁表項(xiàng)PTE的Present標(biāo)志設(shè)為1,而兩個(gè)沒有映射物理內(nèi)存的虛擬內(nèi)存頁表項(xiàng)的Present位清除。所以這時(shí)訪問那兩塊內(nèi)存,則會導(dǎo)致異常缺頁。
vma就像應(yīng)用程序和內(nèi)核的一個(gè)契約。當(dāng)應(yīng)用程序申請內(nèi)存或者文件映射時(shí),內(nèi)核先響應(yīng)這個(gè)請求,分配或更新虛擬內(nèi)存;但是這些虛擬內(nèi)存并沒有映射到真實(shí)的物理內(nèi)存。而是等到內(nèi)存訪問產(chǎn)生一個(gè)內(nèi)存異常缺頁時(shí)才真正映射物理內(nèi)存。即當(dāng)訪問沒有映射的虛擬內(nèi)存時(shí),由于頁表項(xiàng)的Present位沒有被設(shè)置,所以此時(shí)會產(chǎn)生一個(gè)缺頁異常。vma記錄和頁表項(xiàng)兩個(gè)在解決內(nèi)存缺頁,釋放內(nèi)存以及內(nèi)存swap out都起著重要的作用。下面圖展示了上述情況:
1、一開始堆中只有8kb的內(nèi)存,而且都已經(jīng)映射到物理內(nèi)存;
2、當(dāng)調(diào)用brk()函數(shù)擴(kuò)展堆時(shí),新的頁是沒有映射到物理內(nèi)存的,
3、當(dāng)處理器需要訪問一個(gè)地址,而且這個(gè)地址在上述剛分配的虛擬內(nèi)存中,這時(shí)產(chǎn)生一個(gè)缺頁異常;
4、這時(shí)進(jìn)程向伙伴系統(tǒng)申請一頁的物理內(nèi)存,映射到那塊虛擬內(nèi)存上,并添加頁表項(xiàng),設(shè)置Present位.
以上就是關(guān)于“Linux內(nèi)存布局是怎樣的”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對大家有幫助,若想了解更多相關(guān)的知識內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。