說在前面的話:
os記憶體管理
os的中斷、異常、系統呼叫
計算機記憶體越來越大,但是軟體的記憶體開銷也是隨之增加的,計算機系統總是會出現記憶體不夠的問題,於是出現了以下幾種辦法來解決記憶體空間不夠的問題:
覆蓋(overlay)
應用程式手動把需要的指令和資料儲存在記憶體中,這項技術的關鍵代表就是ms-dos作業系統。
虛擬記憶體(virtual memory)
在有限容量的記憶體中,以頁為單位自動狀圖更多更大的程式。
下面一一敘述.
介紹覆蓋技術的方法是,依據程式的邏輯結構,將程式劃分為若干的功能模組,將不會同時執行的模組放在一塊共享記憶體區域內。覆蓋技術中主要設計兩大部分:
這裡主要是考慮**之間的呼叫邏輯,比如上圖,有乙個程式,一共有a~f幾個模組,模組之間的呼叫資訊如樹狀圖所示。於是我們可以確地,b和c肯定不會在同一時刻呼叫,但總有乙個會被呼叫,def同理,那麼我們只需要開乙個空間,空間的大小是多少呢?就是可能被呼叫的程式的最大記憶體空間。
不足覆蓋技術還是比較老的技術,其中增加了程式設計師的程式設計困難,需要去劃分功能模組,確定他們之間複雜的呼叫關係,個人感覺,也不太符合當今oop的思想
。此外,這種從外存裝入覆蓋模組的時間開銷比較大。
介紹交換技術和覆蓋技術有很大的相似之處,關鍵區別是,交換是針對某個程序來說的(process),而覆蓋技術是對某個程序中的某些模組來說的(module),如下圖:
每次swap in和swap out的物件都是某個程序(或者說程式),而且這一過程完全由os來管理,不需要程式設計師控制。說明一點,換入和換出的物理記憶體可以是不一樣的(也應該是不一樣的),位址空間可以使用的基於分頁式的動態位址對映來完成。
不**換技術的粒度可能太大,增加了cpu的開銷。
虛存技術可以看做是上面兩種技術的結合,首先,它也是類似swap的這種換入換出機制,不過粒度不是乙個程序,而是我們之前提到的頁
或者說幀
;此外,虛存也是由os來管理的,我們程式設計師要做的,就是盡量寫出滿足區域性性較好
的**。
什麼是**區域性性?
所謂**的區域性性,就是盡量在寫**時,讓程式在未來執行的過程中的乙個較短時間內,所執行的指令位址和指令的運算元位址盡量在乙個小範圍區域內,這樣cpu可以在較短的時間內訪問資料及執行指令。如果你不是很理解,請看下面這個例子:
我們都知道,c語言中的陣列在記憶體空間中是按行優先的順序進行儲存的,即a[0]、a[1]、a[2]…a[n]的順序,二維陣列類似,可以看作是一維陣列的陣列,即a[0][0]、a[0][1]、a[0][2]…a[0][n],a[1][0]、a[1][1]、a[1][2]…a[1][n],a[3][0]、a[3][1]、a[3][2]…a[3][n]的順序。
現在,假設我們的機器是32位的,所以int就是4位元組長度了,並且每個程序只能被分配到乙個物理幀,假設頁面大小為4k(還記得頁的概念嗎? 他是虛擬記憶體中的乙個概念,和物理記憶體幀的大小一致),也就是1024個int的長度,現在你在寫程式的時候,開了乙個int array[1024][1024]
,這就是1024個頁的大小了,陣列的每一行佔一頁。
現在,我們要遍歷這個陣列,你可以按照以下兩種方式。
按行遍歷
fot(int i=0;i<1024;i++)
的**。這也是在虛擬記憶體管理方式下,我們程式設計師需要關注的地方,寫出更好的**。{ fot(int j=0;j<1024;j++)
{ cout按列遍歷
fot(int j=0;j<1024;j++)
{ fot(int i=0;i<1024;i++)
{ cout如果按列遍歷,那麼我們每得到下乙個值,都會因為需要遍歷的資料在下乙個頁中,總共會發生缺頁故障1024*1024次,而按行遍歷智慧型產生1024次,按列遍歷需要頻繁的頁換入換出,這樣的**就是區域性性不好
虛存的管理是基於段或基於頁式的,大多數教科書上都是以按頁的模式來講解的,在該基礎上,增加請求調頁和頁面置換的思路如下:
所以,關鍵就是如何處理缺頁異常?在講解具體缺頁異常如何處理之前,我們有必要對之前講過的頁表複習一下(還記得嗎?頁表就是實現虛擬位址到物理位址對映時的乙個工具)
解釋:
邏輯頁號:虛擬記憶體記憶體中的概念,也就是使用者程序看到的記憶體空間,實際執行時會將乙個
(virtualpagenum,offset)
的二元組去查頁表,得到實際記憶體位址。駐留位:指的是當前該頁號i對應的頁是否真的在記憶體裡面,如果在,駐留位為1,否則為0。這就是判斷是否出現缺頁異常的關鍵。
修改位:這個主要是用在頁的swap-out過程。你想,假如乙個頁在執行的時候先從外存(硬碟)匯入記憶體中,然後執行的時候只是簡單的讀了下這個頁中的資訊,而沒作相應修改,這樣,在這個頁被swap-out的時候,為了減少磁碟i/o,我們就可以不用將這個頁當前記憶體中的資料匯出到匯入時對應的磁碟空間中去了。執行時修改了頁,修改位為1,否則為0.
訪問位:這個是用來標記該頁是否被訪問,主要是用在頁替換演算法中的。
保護位:有些頁可能是唯讀、可讀寫、可執行等。
若在記憶體中如果有空閒的物理幀(不需要換入換出,就是簡單的匯入),就分配乙個物理頁幀,記為f,轉向第5步。
(此時必定是需要換入換出頁)依據頁面置換演算法選擇即將被替換的物理頁幀f,以及對應的邏輯頁q
如果q被修改過(修改位==1),則把它寫會外存
修改q的頁表項駐留位為0(因為已經被換出了)
將新來的需要訪問的頁p裝入到物理頁幀f中
修改p的頁表項駐留位為1(因為現在被換入了),並設定其對應的物理頁幀為f
重新執行缺頁異常前的指令。
其實圖示已經很清楚了,沒看明白的話,可以參考我上面寫的解釋,特別是括號裡面的東西。
虛存管理的開銷
我們都知道,記憶體的訪問時間是快的(在ns級別),而硬碟的操作較慢(在ms級別),之前差了6個數量級,由此可知,虛擬記憶體的管理方式的開銷在於出現缺頁異常時帶來的硬碟讀寫耗時,有如下圖的總結公式:
觀察eat表示式可知,p越小,則eat越小。p怎麼減小?盡量讓他少缺頁。怎麼少缺頁?right, **區域性性好!
[1] 清華大學 作業系統(operating systems) (2019) 第八講 虛擬儲存概念
虛擬記憶體管理
定義 虛擬記憶體是計算機系統記憶體管理的一種技術。它使得應用程式認為它擁有連續的可用的記憶體 乙個連續完整的位址空間 而實際上,它通常是被分隔成多個物理記憶體碎片,還有部分暫時儲存在外部磁碟儲存器上,在需要時進行資料交換。我的理解 程序例項在使用者態並不直接操作物理記憶體位址,實際物理記憶體是可能是...
段頁結合的實際記憶體管理 虛擬記憶體 OS
如何讓作業系統既支援段又支援頁?虛擬記憶體 我們讓應用程式分為段,然後對映到一段虛擬記憶體中,再讓虛擬記憶體對映到物理記憶體中的頁中,這樣就完成了段和頁的結合 段 頁同時存在時的重定位 位址翻譯 乙個實際的段 頁式記憶體管理 記憶體管理核心 記憶體分配 使用記憶體分為五步 1.分配段 建段表 for...
3 2 虛擬記憶體管理
3.2.1 虛擬記憶體的基本概念 1 傳統儲存管理方式的特徵 各種記憶體管理策略都是為了同時將多個程序保證在記憶體中以便允許多道程式設計。它們都具有以下兩個共同的特徵 1 一次性 作業必須一次性全部裝入記憶體後,方能開始執行。這會導致兩種情況發生 當作業很大,不能全部被裝入記憶體時,將使該作業無法執...