虚拟存储器i
? ? ? 虛擬內存提供了的三個重要的能力:(1)它將主存看成是一個存儲在磁盤上的地址空間的高速緩存,在主存中只保存活動區域,并根據需要在磁盤和主存之間來回傳送數據,通過這種方式,他高效地使用了主存。(2)它為每個進程梯控了一致的地址空間,從而簡化了存儲器管理.(3)它保護了每個進程的地址空間不被其他進程破壞。
? ? ? 虛擬存儲器被組織成一個由存放在磁盤上的N個連續字節大小的單元組成的數組。虛擬存儲器的內容是被緩存在主存中的,他們通過頁進行交換。術語DRAM緩存表示虛擬存儲器系統的緩存,它在主存中緩存許頁。任意時刻,虛擬頁面都分為三個不相交的子集:
?
? ? ? ? ?頁表存放在物理存儲器中,,它將虛擬頁面映射到物理頁面,頁表條目稱為PTE,包含有效位和地址位,地址位包含物理頁號,如果有效位為1,則其地址位指向DRAM中相應的物理頁的首地址,表示已緩存,如果有效位為0,若地址位為空,則該虛擬頁未分配,否則其地址位指向該虛擬頁在磁盤上的起始位置。
?
? ? ? ?當DRAM緩存不命中時稱為缺頁,會觸發一個缺頁異常,缺頁異常調用內核中的缺頁異常處理程序,該程序會選擇一個犧牲頁,并從磁盤中拷貝所需要的虛擬頁到物理存儲器,,更新頁表的內容,隨后返回,返回時,它會重新啟動引起缺頁異常的指令,這時指令可以正常執行。
地址翻譯的步驟如下:
頁命中:
? ? ? 第一步:處理器生成一個虛擬地址,并把它傳給MMU。
? ? ? 第二步:MMU生成PTE地址,并從高速緩存/主存中請求得到它。
? ? ? 第三步:高速緩存/主存向MMU返回PTE。
? ? ? 第四步:MMU構造物理地址,并把它傳送給高速緩存/主存。
? ? ? 第五步:高速緩存/主存返回所請求的數據字給處理器。
頁不命中:
? ? ? 第一步:處理器生成一個虛擬地址,并把它傳給MMU。
? ? ? 第二步:MMU生成PTE地址,并從高速緩存/主存中請求得到它。
? ? ? 第三步:高速緩存/主存向MMU返回PTE。
? ? ? 第四步:PTE中的有效位為0,MMU觸發缺頁異常,傳遞CPU中的控制到操作系統內核中的缺頁異常處理程序。
? ? ? 第五步:缺頁處理程序確定出物理存儲器中的犧牲頁,如果這個頁面已經修改過,則把它換出到磁盤。
? ? ? 第六步:缺頁處理頁面調入新的頁面,并更新存儲器中的PTE。
? ? ? 第七步:缺頁處理程序返回到原來的進程,并再次執行引起缺頁異常的指令。
?
?
? ? ? ? ?物理尋址的高速緩存和虛擬存儲器結合的主要思路是地址翻譯發生在高速緩存查找之前,頁表條目可以緩存,就像其他的數據字一樣。
? ? ? TLB是一個小的、虛擬尋址的緩存,其中每一行都保存著一個由單個PTE組成的塊。TLB通常具有較高的相連性。如圖所示,用于組選擇和行匹配的索引和標記字段是從虛擬地址中的虛擬頁號中提取出來的。
? ? ? 下圖展示了TLB命中時所包括的步驟。這里的關鍵是,所有地址翻譯步驟都是在芯片上的MMU中執行的,因此非常快。
? ? ?第一步:CPU產生一個虛擬地址。
? ? ?第二步和第三步:MMU中TLB中取出相應的PTE。
? ? ?第四步:MMU將這個虛擬地址翻譯成一個物理地址,并且將它發送到高速緩存/主存。
? ? ?第五步:高速緩存/主存將所請求的數據字返回給CPU。
? ? 當TLB不命中時,MMU必須從L1緩存中取出相應的PTE,新取出的PTE存放在TLB中,可能會覆蓋掉一個已經有的條目。
?
多級頁表:
? ? 多級頁表作為一種層次結構的頁表,的作用是用來壓縮頁表。使用層次結構的頁表從兩個方面減少了對存儲器的要求。第一,如果一級頁表中的一個PTE是空的,那么相應的二級頁表就根本不會存在,這代表著一種巨大的潛在節約。第二,只有一級頁表才需要總在主存中,虛擬存儲器可以在需要時創建、頁面調入或者調出二級頁表,這就減小了對主存的壓力,只有經常使用的二級頁表才需要存在主存中。
? ? ?下圖是使用K級頁表的地址翻譯。
Linux虛擬存儲器系統
?
? ? ? ?Linux將虛擬存儲器組織成一些區域的集合,也叫做段的集合,一個區域就是已分配的虛擬存儲器的連續片,這些頁是以某種方式相關聯的,例如代碼段、數據段、堆和共享段。每個虛擬頁面都被保存在某個區域中,而不屬于某個區域的虛擬頁是不存在的。區域的概念允許虛擬地址空間有間隙。
? ? ?內核為系統中的每個進程維護一個單獨的任務結構(源代碼中的task_struct)。任務結構中的元素包含或者指向內核運行運行該進程所需要的所有信息,例如PID和指向用戶棧的指針等等。
? ? ? ?上圖中的pdg字段指向第一級頁表的基址,而mmap指向一個vm_area_structs(區域結構)的鏈表,其中每個vm_area_structs都描述了當前虛擬地址空間的一個區域。當內核運行這個進程時,就把pdg存放在CR3控制寄存器中。
? ? ? Linux的缺頁異常處理,第一步先檢查它訪問的虛擬地址A是不是合法額,換句話說A是否在某個區域結構定義的區域內。第二部檢查試圖進行存儲器訪問是不是合法的,也就是說進程是否有讀寫或者執行這個區域內頁面的權限。第三步,執行正常的頁面交換。
存儲器映射:
? ? ?Linux通過將一個虛擬存儲器區域與一個磁盤上的對象關聯起來,以初始化這個虛擬存儲器區域的內容,稱之為存儲器映射。虛擬存儲器區域可以映射到兩種類型的對象的一種:(1)Uinx文件系統中的普通文件,一個區域可以映射到一個普通磁盤文件的連續部分。文件區被分為頁大小的片,每一片包含一個虛擬頁面的初始內容。因為執行按需進行頁面調度,所以這些虛擬頁面沒有實際交換進入物理存儲器,知道CPU第一次引用到頁面。(2)匿名文件,匿名文件由內核創建,包含的全是二進制0.映射到匿名文件的頁面有時也叫做請求二進制0的頁,因為是用二進制0覆蓋犧牲頁,因此此時磁盤和存儲器之間沒有實際的數據傳送。
?
共享對象:
? ? ?一個對象可以被映射到虛擬存儲器中的一個區域,要么作為共享對象,要么作為私有對象。對共享對象的任何寫操作對于所有共享這個對象的進程都是可見的。
? ? ? ?私有對象是使用一種寫時拷貝的技術被映射到虛擬存儲器中的。在物理存儲器中只保留私有對象的一份拷貝,對于每個映射到私有對象的進程,相應的私有區域的頁表條目都被標記為只讀,并且區域結構被標記為私有的寫時拷貝。當有進程試圖寫私有區域某個頁面時,就會觸發一個保護故障。當保護故障注意到保護異常是由于進程試圖寫私有寫時拷貝的頁面而引起的,它就會在物理存儲器中創建這個頁面的一個新的拷貝,更新頁表條目指向這個新的拷貝,然后恢復這個頁面的可寫權限。當故障返回時,CPU重新執行這個寫操作。
?fork函數
? ? ? 當fork函數被當前的進程調用時,內核為新進程創建各種數據結構,bing分配給它唯一的PID。為了給這個新的進程創建虛擬存儲器,它創建了當前進程的mm_struct、區域結構和頁表的原樣拷貝。它將兩個進程中的每個頁面都標記為只讀,每個區域結構都標記為私有的寫時拷貝。因此fork函數返回時,新進程現在的虛擬存儲器剛好和調用fork時存在的虛擬存儲器相同。通過寫時拷貝保持了私有地址空間的抽象概念。
execve函數
? ? ? 用于加載并運行函數,需要步驟如下:
? ? ? 可以用mmap函數來創建新的虛擬存儲器區域,并將對象映射到這些區域中。
動態存儲器分配
? ? ?動態存儲器分配器維護著一個進程虛擬存儲器,稱為堆。分配器將堆視為一組不同大小的塊的集合來維護。每個塊就是一個連續的虛擬存儲器片,要么是已分配的,要么是空閑的。造成堆的利用率低的主要原因是碎片,有兩種形式:外部碎片和內部碎片。分配器在對空閑塊的管理策略上,有用隱式空閑鏈表和顯示空閑鏈表。分配器有兩種類型,顯示分配器要求應用顯示地釋放它們的存儲器塊。隱式分配器(垃圾收集器)自動釋放任何未使用的和不可達的塊。
?
轉載于:https://www.cnblogs.com/linear/p/6802739.html
總結
- 上一篇: android端 socket长连接 架
- 下一篇: Spark in meituan ht