天天看點

程序的虛拟位址空間(分段/分頁)

演變過程

早期的記憶體分派過程:運作起來一個程序就會從記憶體中配置設定一塊連續的空間提供其使用,這樣存在很多的問題

1)記憶體使用率低,當我擁有了足夠大的空間不一定能夠運作起來對應大小的程式,見下圖

2)缺乏通路控制,當我的一個程式惡意的去該表另一個程式的資料時,并不會受到限制,這樣會造成嚴重的後果

3)程式運作的位址不确定,因為所有位址都是實體位址,隻有程式運作起來才能夠知道

程式的虛拟位址空間(分段/分頁)

分段

為了解決以上問題,采用了分段式記憶體管理,就是增加一個中間層,利用一種間接的位址通路方法通路實體記憶體,程式中通路的記憶體位址不再是實際的實體記憶體位址,而是一個虛拟位址,然後由作業系統将這個虛拟位址映射到适當的實體記憶體位址上,這樣就可以保證記憶體通路控制,程式本身隻能通路本身的虛拟位址,虛拟位址被作業系統映射到實體位址,隻要作業系統確定映射到的實體位址的隔離性,就可以最終實作程式隔離的作用

程式的虛拟位址空間(分段/分頁)

分頁&&虛拟位址空間

但是分段雖然解決了記憶體通路控制的問題,但是它并不能解決記憶體使用率低的問題,于是提出分頁式記憶體管理 ,分頁式記憶體管理可以将一段程式加載到不連續的實體空間上,但是從虛拟位址空間來看依舊是連續的,這樣就可以解決記憶體使用率低的問題

1)首先解釋程序的虛拟位址空間

一個運作起來的程序作業系統都維護了一個task_struct結構體,存儲了程序的資訊,其中有一個mm_struct類型的結構體指針,這個指針指向的就是程序的虛拟位址空間

實作方式:mm_strcut結構體也叫記憶體描述符,其中記錄了各個段的起始位址,終了位址,通過這種方式描述了程序的虛拟位址空間

程式的虛拟位址空間(分段/分頁)

2)分頁

不管是虛拟位址空間還是實體位址空間,作業系統都将其分為了一個個大小相同的記憶體頁,假設頁大小為4k,那麼對于一個4G的記憶體,就有大約100多萬個記憶體頁,記憶體位址分為頁号(前20位)頁内偏移(後12位)

程式的虛拟位址空間(分段/分頁)

頁表: 頁表中存儲的是一個虛拟位址和一個實體位址的映射關系,映射方法是通過虛拟位址頁号在頁表中找到對應的實體頁号,将虛拟位址頁号偏移作為實體位址頁号偏移,組成實體位址,頁表除了映射虛拟位址和實體位址外,還标記了實體位址的通路權限

程式的虛拟位址空間(分段/分頁)

分析上圖:程序task_struct結構體中有個mm_strcut結構體,這個結構體就是虛拟位址空間,頁表将虛拟位址空間映射到實體位址空間,實體位址空間不一定是連續的,但是虛拟位址空間可以做到連續,既保證了記憶體通路控制,也保證了記憶體的使用率

對于父程序和子程序,因為建立子程序時是拷貝父程序得到,并且利用寫實拷貝技術,是以建立了子程序還沒有改變資料的時候,父子程序共享同一份資料,例如一個變量g_val,那麼父子程序變量位址相同,但是你會發現即使改變了一方的資料(資料不同一定存儲在不同的位址上)得到的變量位址依舊相同,這是因為得到的并不是實體位址,而是虛拟位址,虛拟位址雖然相同但是通過不同的頁表映射到不同的實體位址上

通路記憶體的過程: 當通路虛拟記憶體時,會通過虛拟位址頁号通路 MMU(記憶體管理單元) 去比對對應的實體位址頁号,如果找不到虛拟記憶體和實體記憶體的映射關系,會産生缺頁中斷,從磁盤中取得缺的頁放入記憶體,如果記憶體已滿,還會根據某種算法将磁盤中的頁換出(MMU中存儲頁表,用來比對虛拟記憶體和實體記憶體),找到後将虛拟位址頁内偏移作為實體位址頁内偏移進而構成實體位址

段頁式記憶體管理

程式的虛拟位址空間(分段/分頁)

段頁式通路記憶體的過程: 通過段号在段表中找到對應的段内頁表資訊,通過段内頁号在頁表中找到對應的實體頁号,找到後将虛拟位址頁内偏移作為實體位址頁内偏移進而構成實體位址

多級頁表

對于一個4G的記憶體,頁表就有100多萬個頁表項,而這麼多頁表項我們并不是每個都能用到,每個程序我們都建立一個這樣的頁表也太浪費了,是以可以建立一個二級頁表,這個二級頁表專門管理一級頁表,隻有用到了我才給程序配置設定,類似于一級頁表管理實體位址,隻有用到了實體位址我才給程序開辟空間,否則我就不開辟

本部落格兩張彩色圖檔來源

分頁記憶體管理&&虛拟位址空間的好處

1)記憶體通路控制

2)實體位址的使用率高

3)保證程序的獨立性

寫時拷貝技術

父程序建立了子程序,但是并沒有直接給子程序開辟記憶體,拷貝資料,而是跟父程序映射到同一位置,但是如果記憶體中資料發生了改變,那麼對于改變的這塊記憶體,需要重新給子程序開辟記憶體,并且更新頁表資訊。提高子程序建立性能

繼續閱讀