目錄
引言
虛擬內存
頁表
單級頁表
頁表項
單級頁表的不足
二級頁表
四級頁表
快表TLB
結語
引言
一個系統中,CPU和內存是被所有進程共享的,而且一個系統中往往運行著多個進程。如果一個進程不小心寫了另一個進程的內存,那么被寫入的進程可能會發生一些迷惑行為。
虛擬內存
一個進程,只有在它運行起來的時候才知道它實際占用哪塊內存,程序員在寫代碼的時候是無法確定的。為了實現獨立編址,既不考慮內存是否能容納整個程序,也不考慮程序最終是在內存中的什么位置,大佬們突發奇想,能不能等到程序運行時,才為每一個程序分配一定的運行空間,由地址轉換部件將編程時的地址轉換成實際物理內存中的地址呢??當然可以!于是,就引入了虛擬內存技術。
關于什么是虛擬內存,舉個例子:假設你開了一家“超能快遞公司”,但真實的倉庫(物理內存)只有一塊很小的場地(比如100㎡)。不過你打廣告說:“我們有10個足球場大的貨架空間!(虛擬內存)” —— 吸引無數顧客(程序)來寄送快遞。
說白了虛擬內存本質上就是騙程序,讓每個程序以為自己獨占整個內存。它有以下幾個優勢:
1)?內存隔離與保護:每個程序擁有獨立的虛擬地址空間,避免程序間直接訪問彼此內存。
2)?簡化編程模型:程序員無需關心物理內存的實際分配情況。
頁表
頁表是操作系統內存管理中的核心數據結構,用于實現虛擬地址到物理地址的轉換。它由操作系統的內存管理單元MMU來維護。每個進程都有自己的頁表,頁表實際上還對內存起到了保護的作用,在虛擬地址到物理地址轉換的頁表項里,設置了權限位,如果權限不夠,我們是拿不到對應的物理地址的,這對內核的數據起到了保護的作用。關于頁表項的權限位后面再詳細介紹。
可以先通過上面這張圖在腦海里建立一個虛擬地址到物理地址轉換的模型,后面我們在持續填充細節。?
單級頁表
單級頁表的地址轉換過程:
首先介紹一下虛擬地址的格式:它由兩部分組成,一部分是頁號,另一部分是頁內偏移。頁號是用來找到頁表中的頁表項,頁表就是一個連續的空間,頁號就是要找頁表項在頁表中的偏移量,相當于數組下標。頁內偏移,是指在物理內存頁中的偏移,單個物理內存頁也是連續的,也可以把它看做一個數組,頁內偏移當做下標。
CR3:它是個寄存器,在進程創建的時候初始化,用來存放當前進程的頂級頁表起始地址。
?CPU發出要訪問的虛擬地址后,可以通過虛擬地址中的頁號加上CR3中存放的頁表起始地址定位到相應的頁表項,一個頁表項的大小是固定的,為4個字節。頁表項里存放著對應物理內存頁起始地址,然后在結合虛擬地址中的頁內偏移,即可得到完整的物理地址,定位到相應位置上。
頁表項
1)P:對應的物理內存頁是否在內存中。1表示在內存中,0表示不在。如果不在,就會出發缺頁中斷,把對應的數據換入內存。
2)RW:表示該進程對該內存頁具有的讀寫權限。1表示具有讀寫權限,0表示具有只讀權限。
3)US:值為0表示該物理內存只有內核才能訪問,值為1表示用戶空間的進程也可以訪問。
4)PWT:值為1表示CPU的cache中數據發生修改后,采用全寫的方式進行同步,為0表示采用寫回的方式進行同步。
5)PCD:表示對應的物理內存頁是否可以緩存在CPU的cache中,1表示不可以,0表示可以。
6)A:表示對應的物理內存最近是否被訪問過。1表示被訪問過,0表示沒有。CPU的內存管理單元MMU會經常檢查該位置,來判斷對應的物理內存頁是否活躍,作為換入換出的依據。
后面幾個就不介紹了~
單級頁表的不足
有了上面的認識,我們知道:一個頁表項大小為4B,它可以映射一張大小為4KB物理內存頁,一張頁表的大小也是4KB,包含1024個頁表項。
這樣一算,一張頁表可以映射4MB的物理內存。那么32位系統下,內存大小為4GB,就需要1024張頁表。一張頁表4KB,那么一共就是需要4MB的物理內存來存放1024張頁表。但是,隨著系統的運行,很難找到這么一大片的連續空間。更要命的是,每個進程都需要有自己獨立的頁表,就更難找到這么多塊連續的4MB內存空間了。進程一旦多起來,這也是一筆不小的開銷呀~
但是,話又說回來,有必要進程一啟動就給它分配4MB的內存空間去存放那么多張頁表嗎?
根據程序的局部性原理,程序不會在一上來就要訪問所有內存,相反進程對于內存的訪問表現出明顯的傾向性,更傾向于訪問最近訪問過的地址周圍的一些數據。最近訪問過的地址以及它周圍的數據很可能通過同一張頁表就可以找到。
因為單級頁表存在的一些不足,頁表開始向多級頁表演進。
二級頁表
二級頁表就是在單級頁表的基礎上,增加了一個目錄結構。
?相較于單級頁表來說,地址轉換的時候要多一層,同時虛擬地址中也要多保存一級頁號。
一張一級頁表中,也同樣有1024個頁表項,一個頁表項映射一張二級頁表,一張二級頁表映射4MB物理內存。那么一張一級頁表就可以映射4GB的內存。原來單級頁表需要4MB,現在優化到4KB。只有一級頁表常駐在內存中,二級頁表存在磁盤上,根據需要進行換入和換出。
四級頁表
深刻理解了單級頁表和二級頁表以后,其實四級頁表也一樣,在虛擬地址上多了幾級頁號,然后進行地址轉換的時候要多走幾層。
PGD:全局頁目錄 ????????PUD:上層頁目錄????????PMD:中間頁目錄????????PTE:頁表項?
快表TLB
快表,本質上就是MMU的一個緩存,緩存常用頁表項以加速地址轉換。
CPU發出虛擬地址后,MMU首先去快表中查找是否存在對應的頁表項,如果存在就直接返回對應的物理地址,然后通過該地址去緩存中找到對應的數據,然后將數據傳入CPU。以上是快表緩存命中的情況,通過這一過程,也就了解了什么是快表以及它的作用何在了。
結語
頁表的設計永遠需要在「空間效率」、「查詢速度」和「靈活性」之間找到動態平衡,沒有完美的方案,只有適合場景的取舍。
推薦閱讀:https://www.cnblogs.com/binlovetech/p/17571929.html
感謝支持~?