<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【底層原理】Linux內(nèi)存管理

          共 2279字,需瀏覽 5分鐘

           ·

          2020-10-11 12:11


          點擊「閱讀原文」查看良許原創(chuàng)精品視頻。

          作者:羅道文的私房菜

          原文鏈接:http://luodw.cc/2016/02/17/linux-memory/

          今天這篇文章主要是之前看linux內(nèi)核相關(guān)知識和博客Gustavo Duarte中。我(指道文)主要是看了這篇博客,并且結(jié)合之前的知識,對內(nèi)存管理的的理解又上升了一個檔次。所以想通過這篇文章總結(jié)下。

          我們先來看下linux內(nèi)存布局,此圖比我之前寫的那篇文章寫的布局更詳細

          在linux中,每一個進程都被抽象為task_struct結(jié)構(gòu)體,稱為進程描述符,存儲著進程各方面的信息;例如打開的文件,信號以及內(nèi)存等等;然后task_struct中的一個屬性mm_struct管理著進程的所有虛擬內(nèi)存,稱為內(nèi)存描述符。在mm_struct結(jié)構(gòu)體中,存儲著進程各個內(nèi)存段的開始以及結(jié)尾,如上圖所示;這進程使用的物理內(nèi)存,即常駐內(nèi)存RSS頁數(shù),這個內(nèi)存使用的虛擬地址空間VSZ頁數(shù),還有這個進程虛擬內(nèi)存區(qū)域集合和頁表。

          從上面這個圖可以看出,進程是有代碼段Text segment,數(shù)據(jù)段(已初始化的全局,靜態(tài)變量),BSS段(未初始化的全局,靜態(tài)變量),內(nèi)存映射區(qū)以及

          每一塊虛擬內(nèi)存區(qū)(VMA)都是由一塊連續(xù)的虛擬地址組成,這些地址從不覆蓋。一個vm_area_struct實例描述了一塊內(nèi)存區(qū)域,包括這塊內(nèi)存區(qū)域的開始以及結(jié)尾地址;flags標志決定了這塊內(nèi)存的訪問權(quán)限和行為;vm_file決定這塊內(nèi)存是由哪個文件映射的,如果沒有文件映射,則這塊內(nèi)存為匿名的(anonymous)。上述圖中提到的每個內(nèi)存段,都對應(yīng)于一個vm_area_struct結(jié)構(gòu)。如下圖所示

          上圖即為/bin/gonzo進程的內(nèi)存布局。程序的二進制文件映射到代碼段和數(shù)據(jù)段,代碼段為只讀只執(zhí)行,不可更改;全局以及靜態(tài)的未初始化的變量映射到BSS段,為匿名映射,堆和棧也是匿名映射,因為沒有相應(yīng)的文件映射;內(nèi)存映射區(qū)可以映射共享庫,映射文件以及匿名映射,所以這塊內(nèi)存段可以是文件映射也可以是匿名映射。而且不同的文件,映射到不同的vm_area_struct區(qū)。

          這些vm_area_struct集合存儲在mm_struct中的一個單向鏈表和紅黑樹中;當輸出/proc/pid/maps文件時,只需要遍歷這個鏈表即可。紅黑樹主要是為了快速定位到某一個內(nèi)存塊,紅黑樹的根存儲在mm_rb域。

          之前介紹過,線性地址需要通過頁表才能轉(zhuǎn)換為物理地址。每個進程的內(nèi)存描述符也保存了這個進程頁表指針pgd,每一塊虛擬內(nèi)存頁都和頁表的某一項對應(yīng)。

          虛擬內(nèi)存是不存儲任何數(shù)據(jù)的,它只是將地址空間映射到物理內(nèi)存。物理內(nèi)存有內(nèi)核伙伴系統(tǒng)分配,如果一塊物理內(nèi)存沒有被映射,就可以被伙伴系統(tǒng)分配給虛擬內(nèi)存。剛分配的物理內(nèi)存葉框可能是匿名的,存儲進程數(shù)據(jù),也可能是也緩存,存儲文件或塊設(shè)備的數(shù)據(jù)。一塊虛擬內(nèi)存vm_area_struct塊是由連續(xù)的虛擬內(nèi)存頁組成的,而這些虛擬內(nèi)存塊映射的物理內(nèi)存卻不一定連續(xù),如下圖所示:

          如上圖所示,有三個頁映射到物理內(nèi)存,還有兩個頁沒有映射,所以常駐內(nèi)存RSS為12kb,而虛擬內(nèi)存大小為20kb。對于有映射到物理內(nèi)存的三個頁的頁表項PTE的Present標志設(shè)為1,而兩個沒有映射物理內(nèi)存的虛擬內(nèi)存頁表項的Present位清除。所以這時訪問那兩塊內(nèi)存,則會導致異常缺頁。

          vma就像應(yīng)用程序和內(nèi)核的一個契約。當應(yīng)用程序申請內(nèi)存或者文件映射時,內(nèi)核先響應(yīng)這個請求,分配或更新虛擬內(nèi)存;但是這些虛擬內(nèi)存并沒有映射到真實的物理內(nèi)存。而是等到內(nèi)存訪問產(chǎn)生一個內(nèi)存異常缺頁時才真正映射物理內(nèi)存。即當訪問沒有映射的虛擬內(nèi)存時,由于頁表項的Present位沒有被設(shè)置,所以此時會產(chǎn)生一個缺頁異常。vma記錄和頁表項兩個在解決內(nèi)存缺頁,釋放內(nèi)存以及內(nèi)存swap out都起著重要的作用。下面圖展示了上述情況:

          1、一開始堆中只有8kb的內(nèi)存,而且都已經(jīng)映射到物理內(nèi)存;

          2、當調(diào)用brk()函數(shù)擴展堆時,新的頁是沒有映射到物理內(nèi)存的,

          3、當處理器需要訪問一個地址,而且這個地址在上述剛分配的虛擬內(nèi)存中,這時產(chǎn)生一個缺頁異常;

          4、這時進程向伙伴系統(tǒng)申請一頁的物理內(nèi)存,映射到那塊虛擬內(nèi)存上,并添加頁表項,設(shè)置Present位.

          自此,這個內(nèi)存管理暫時就說到這。總結(jié)下:

          1、linux進程的內(nèi)存布局的每個段都是有一個vm_area_struct,而這個實例是由連續(xù)的虛擬內(nèi)存地址組成;

          2、當請求內(nèi)存時,先是擴展vm_area_struct或者新分配一個vm_area_struct,但是并不映射物理內(nèi)存,只有等到訪問這塊內(nèi)存時,產(chǎn)生缺頁異常,內(nèi)核才分配物理內(nèi)存。



          良許個人微信


          添加良許個人微信即送3套程序員必讀資料


          → 精選技術(shù)資料共享

          → 高手如云交流社群





          本公眾號全部博文已整理成一個目錄,請在公眾號里回復「m」獲取!

          推薦閱讀:

          手機沒網(wǎng)了,卻還能支付,這是什么原理?

          Sampler:Shell命令執(zhí)行可視化和告警工具

          拆了公司發(fā)的中秋禮包,我竟然要被全員批評!


          5T技術(shù)資源大放送!包括但不限于:C/C++,Linux,Python,Java,PHP,人工智能,單片機,樹莓派,等等。在公眾號內(nèi)回復「1024」,即可免費獲取!!


          瀏覽 77
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  91吊逼| 日本中文字幕A√ | 婷婷电影网 | 天天大逼视频 | 爱搞在线国产 |