windows核心 記憶體管理

2021-09-02 14:12:36 字數 3820 閱讀 6303

一、幾個基本的概念

1.儲存器的金字塔結構

儲存器從下之上依次是磁碟/flash、dram(記憶體)、l2-cache、l1-cache、暫存器,越在上面的儲存器訪問速度越快,同時**也越昂貴,每一級都可以看做是下一級的快取,記憶體是磁碟的快取,cache是記憶體的快取。

2.位址空間

3.頁將物理記憶體和虛擬記憶體按頁來劃分,頁的大小也有所不同,arm中支援1m的大頁,4k或64k的細頁,x86下支援4m的大頁,利用頁表來表徵整個位址空間,當採用二級頁表時,存在乙個頁目錄,用來索引對應頁表所在的實體地址,pte頁表項佔4個位元組,當採用4k大小的頁時,乙個虛擬位址可以劃分為:

31            22 21             12 11               0

|  頁目錄索引   |     頁表索引    |    頁內偏移      | 

硬體頁表項pte

31            22                                     0

|  物理頁幀號   |     物理頁屬性和訪問控制           |

二、位址轉譯

位址的轉譯是有虛擬位址至實體地址,處理器內使用的是虛擬位址,經過mmu轉譯為實體地址,例如dma使用的就是實體地址,因為它在mmu之後,轉譯的過程是mmu與os配合完成的,os負責維護頁表,mmu負責翻譯,要明確一點是mmu使用的是實體地址。首先根據頁目錄的實體地址(x86在cr3中)和頁目錄索引查詢到頁目錄表項pde,其中記錄了對應頁表的實體地址,如果該頁表在物理記憶體中(頁表也可以被換出到磁碟中),pde表項的格式與硬體pte基本一致,然後根據頁表索引找到對應的頁表項pte,最後根據其中的物理頁幀號和頁內偏移計算得到實體地址。

具體的翻譯過程用乙個例子來說明:

例如:乙個虛擬位址為0x50001,頁目錄索引為0x0,頁表索引為0x50,頁內偏移為0x1,首先找到pde(windows的虛擬位址空間pde_0的va = 0xc0300000),pde實體地址 = cr3 + 0x0(頁目錄索引)*4,pde表項內容為0x00700 067,查詢pte,pte實體地址 = 0x700 + 0x50(頁表索引)*4,(pte的虛擬位址為0xc0000140),pte表項的內容為0x00e63 047,則最終轉譯的實體地址 = 0xe63 000 + 0x1 = 0xe63001

三、虛擬記憶體的原理

如何在物理記憶體有限的情況下例如只有32mbyte,可以使系統定址4g的位址空間,物理記憶體資源是一種共享的稀缺資源,因此虛擬位址空間的頁並不是都有對應的物理記憶體頁面,將某一時刻處理器不訪問的虛擬頁面以頁的方式儲存在磁碟上,當需要讀寫時再將其換入至物理記憶體中。

四、程序虛擬位址空間

x86體系結構下,乙個程序的虛擬位址空間為4g,主要包括了程序的私有位址空間和系統位址空間兩部分,windows中0x0--0x7fff ffff作為程序私有,0x8000 0000 -- 0xffff ffff為系統位址空間。

1.大頁和小頁

採用大頁的好處是在tlb中可以快取更大的位址空間,增加了快取命中的概率,不好的一點是頁面粗粒度造成的不安全訪問,例如.data(讀寫)和.text(唯讀)都放在同乙個具有讀寫許可權的頁面內,則有可能造成.text的內容誤寫,可能導致系統崩潰。

採用小頁的好處是細粒度管理記憶體,更加靈活,更少的內部碎片,但同時pfn更多,管理的開銷要更大一些。

因此為了安全可靠,選用小頁,4k page

2.延遲計算

(1)先保留再提交記憶體

當乙個執行緒申請大塊的虛擬記憶體時,現在虛擬位址空間中保留一段範圍,為一塊虛擬記憶體建立虛擬位址描述符(vad),當真正訪問這段位址空間時,再建立pte,也就是在物理記憶體中分配有效的頁面。乙個應用例子就是每個執行緒的使用者棧在建立時首先會保留1mb的空間,只有在虛擬頁面被訪問時才會提交。在vad中記錄了位址範圍的大小,以及讀寫許可權,當建立pte時就根據vad中記錄的資訊(讀寫許可權)來填充pte。

(2)寫時複製 copy-on-wirte

i.當兩個程序共享乙個寫時複製的物理頁面時,如果其中乙個程序中的執行緒要對共享頁面進行寫操作,則產生乙個記憶體管理錯誤(乙個異常),記憶體管理器為其分配乙個新的讀寫物理頁面,並且將原始共享頁面的內容複製到新的物理頁面中,並將虛擬位址對映更新為新的物理頁面,控制權返回執行緒,執行緒執行寫操作,此時新的物理頁面屬於該程序私有,其他程序是看不到的,也就是說寫時複製為執行寫操作的程序建立了乙份私有的拷貝。

ii.posix子系統利用寫時拷貝來建立子程序的位址空間,首先父程序建立乙個子程序,子程序的位址空間是共享父程序的位址空間,將位址空間標記為寫時拷貝,只有子程序執行寫操作時,才會拷貝相應的頁面給子程序私有使用。

3.記憶體區物件

section object,每乙個開啟的檔案都有乙個記憶體區物件指標,根據檔案型別的不同(資料檔案或可執行檔案)指向不同的控制區域(虛擬位址空間內),控制區域包括子記憶體區,例如乙個可執行檔案的子記憶體區就是.data,.text,.bss等,同時這個控制區域又指向了一些原型pte,通過這些原型pte可對映到該記憶體區物件所對映的實際物理頁面。

當記憶體區物件指向乙個很大的資料檔案時,執行緒只訪問其中的一部分,就只對映該記憶體區中的一部分,這部分被稱為記憶體區檢視。

記憶體區物件的應用,映像載入器利用它載入可執行檔案,快取管理器利用它來訪問快取檔案中的資料,這兩者都是針對開啟的檔案,共享記憶體的應用是記憶體區物件與物理記憶體關聯。

虛擬頁有三種狀態,已提交的,保留的和未分配的。

4.windows的四種記憶體保護機制

(1)系統空間的全域性資料結構和記憶體池只有在核心模式下才可以訪問,使用者執行緒無法訪問這些頁面

(2)每個使用者程序都有自己的私有位址空間,這部分空間是其他程序無法訪問的

(3)位址轉譯過程中的隱式保護,乙個標記為唯讀的頁在對其進行寫操作時會產生頁面訪問錯誤

(4)共享記憶體區物件具有標準的windows訪問控制列表,對於沒有許可權的程序,是無法訪問共享記憶體區的

5.程序頁表

乙個程序有自己的頁目錄,這個頁目錄就指向了對應的頁表,程序的系統空間都是共享的,因此頁表也是共享系統空間頁表項,乙個程序在建立時會初始化位址空間,也就是初始化頁表,第一階段就是建立系統空間的頁表項,就是將頁目錄的pde指向系統空間的頁表,然後是開啟乙個可執行檔案建立乙個記憶體區物件,再對映至程序的私有空間,實質上是先保留位址空間,當程序執行時根據讀寫頁面的需要建立pte,程序的會話空間頁表也是共享的,即指向已有的會話頁表。程序的頁目錄和頁表所在的物理頁被對映至0xc0300 000和0xc000 0000

6.tlb

tlb就是快取了虛擬頁至物理頁的對映,本質上就是乙個cache,程序切換時會重新整理tlb,但是系統空間的tlb項不會重新整理,因為程序的系統空間是共享的

7.頁面錯誤處理

頁面處理的錯誤有兩種,(1)訪問了沒有物理頁對映的虛擬位址 (2)以錯誤的方式訪問

8.原型pte

首先原型pte是一種無效pte,目的是讓所有可能需要共享頁面的程序的pte都指向原型pte來解決頁面錯誤,原型pte是伴隨這共享頁面的記憶體區一起建立的,當共享記憶體頁面是有效時,程序都直接用自己的pte來訪問。

當共享記憶體頁面無效時,如果沒有原型pte,那如果乙個程序訪問該共享頁面將其換入記憶體中,那記憶體管理器要將所有共享該記憶體頁的程序的頁表進行更新,告訴他們共享記憶體頁有效了,這樣做比較費力。

現在使用原型pte,當程序訪問的共享頁無效時,則將該pte指向共享頁的原型pte,如果程序a再次訪問該頁,共享頁又被換入記憶體中,此時要更新原型pte指向新的物理頁,當程序b再次訪問共享頁時,此時因為原型pte已經得到更新,則記憶體管理器更新程序b的頁表,使其pte指向新的物理頁。

原型pte的精髓還是延遲計算,就是當乙個共享頁從新被換入記憶體時,不必去更新所有曾經訪問過該共享頁的程序頁表,而是等到進**正訪問時再去更新。

9.換頁策略

(1)最近最少使用

(2)先進先出 將駐留在記憶體中最久的頁面換出

(3)時鐘演算法

原文:

linux核心記憶體管理

整個linux虛擬記憶體發布如下 3g以上是核心位址,0 3g是程序位址空間。在x86結構中,核心位址分為三種,這三種型別的區域如下 zone dma 記憶體開始的16mb zone normal 16mb 896mb zone highmem 896mb 結束 程序位址空間的3g,通過mmu,隨機...

linux核心記憶體管理

1.每個程序都有自己的頁面目錄,都是虛擬位址,便於mmu將虛擬位址轉換為實體地址 2.task struct mm struct pgd 3.struct page用來表示乙個物理頁面,在核心中有乙個page的陣列,用來表示當前系統中所有的物理頁面 4.頁面目錄 頁面表 物理頁面起始位址1.物理頁面...

Linux核心 記憶體管理

在棧上靜態分配 高階記憶體的對映 分配函式的選擇 1.32位體系結構支援4kb的頁,如果1gb的物理記憶體,物理記憶體被劃分為262144個頁 2.系統中每乙個物理頁都有乙個struct page結構體 linux核心主要使用四種區 zone highem叫做高階記憶體,其餘的叫做低端記憶體 記憶體...