首先,問大家一個很有趣的問題,有人玩過單片機嗎?有人用過 excel 表格嗎?
相信很多人都沒有把玩過單片機,但是 excel 倒是玩的賊溜,是不是?
沒玩過單片機,哪聽說過單片機有作業系統嗎?能同時運作多個程式嗎?
沒吃過豬肉,還沒見過豬跑麼?單片機是沒有作業系統的,也不能同時運作多個程式!
因為單片機都是把寫好的程式直接燒錄到裝置中去,一旦燒錄了,就不能更改,而且同時隻能讓運作一個程式,不能運作多個。因為,刀片機中的程式是直接操作實體記憶體的。
你可以腦補一下,如果同一個實體記憶體位址被多個程式同時使用,會出現什麼情況?那畫面,簡直不可入腦。 腦殼痛!!!
而我們現在用的 windows 系列、類 unix 系列作業系統,‘智能’ 的為我們設計了一套記憶體管理機制 mmu。
每個程序一運作,就會給他配置設定一個虛拟記憶體 vm 空間,和在記憶體條中配置設定一段實體記憶體 pm 空間。虛拟記憶體裡面的資訊告訴程序,自己要用的記憶體資料,在實體記憶體哪些地方。

每個程序都有配置設定自己的虛拟記憶體,虛拟記憶體中記錄實體記憶體的位置資訊,是以,每個程序的記憶體就被天然的隔離了,不會出現在記憶體條中,搶别的程序資源。
而一個程序要能正常運作,它的實體記憶體中,至少會包括:棧資料、堆資料、代碼資訊、資料資訊,這些在實體記憶體中是分塊存放的,也就是從某一個位置開始,連續一段空間,都是存着相同類型的資料,是以,虛拟記憶體中,要把這些資料的起始位和偏移量都存儲好,這樣,程序要使用某一類資料時,就能快速找到這類資料在記憶體中的位置,進而擷取到資料。
說了一大堆,可能還有很多人沒有明白,下面,整點明白的。
你平時工作中,是不是要整很多 excel 表格,存儲各種工作資訊,你要某些工作資訊時,就打開這個 excel 檔案,這個檔案中有很多個工作表,你要某些資料時,就點選工作表的名稱,打開對應表格,檢視對應資料。
你可以把整個 excel 檔案,了解為程序運作需要的資訊,每一個工作表名稱,就相當于虛拟記憶體,告訴我們,需要的具體資料在哪兒?每一個工作表中資訊,就相當于實體記憶體中存儲的資料,點選工作表名,進入工作表,就能獲得到資料位置。
這個例子,容易了解吧。然後,再對照上面的專業性内容看下,是不是容易了解了?
現在對虛拟記憶體和實體記憶體,是不是有了比較清楚的認識了。
但是,這還不是我們作業系統對記憶體管理的最優辦法,因為,上面講的方法,還存在容易産生記憶體碎片 和 記憶體交換效率不高的問題。
當連續啟動多個程序時,會在記憶體條上配置設定連續的記憶體空間塊,但是,一旦中間某個程序停了,釋放記憶體空間,就會出現記憶體塊不連續,出現記憶體碎片。
此時,如果啟動一個新的程序,如果申請的記憶體空間大于剩餘記憶體空間碎片的大小,就無法申請到記憶體空間而報錯,但是,記憶體的實際總剩餘空間可能又是大于申請的記憶體空間的。
舉個例子,就像你有一個工作表,你開始寫東西時,從第一行開始往下寫,連續行,密密麻麻的寫了很多。結果,你發現其中有些資訊是無效的,不用了,你就把整行資訊删除,但是沒有删除行,這樣,這個工作表,就出現了零碎的空行。現在,你又想利用空行,往裡面寫資料,但是你要寫的資料是多行,行數大于零碎的空行。
你怎麼辦呢?
你是不是想到了,先剪切有資料的行到黏貼闆,然後從空行位置開始黏貼,這樣,是不是就可以把空行整理到一起了?
其實,我們計算機記憶體管理,也有類似的辦法。
在磁盤上虛拟一塊空間,叫 swap 分區,然後,把記憶體中一整段空間,剪切到 swap 分區,然後,再還原回記憶體,這樣,就移動了原來的記憶體空間位置,把空閑的記憶體空間整理到了一起。這個,是不是很容易了解了。
了解是容易了,但是,這個辦法真的很好嗎?
swap 分區,是由磁盤虛拟而來的,它的速度遠遠慢于記憶體速度,而一個程序,它的記憶體空間一般都是幾百兆,如果,一次拷貝一個或幾個程序的記憶體資源到 swap 分區,然後再還原到記憶體,這個時間勢必會很長,使用者就會明顯感覺卡頓,甚至操作無響應。
這又該這麼辦呢?
如果是你,你會不會想,能不能一次不拷貝那麼多、那麼大,每次拷貝小點,分多次拷貝?
計算機也是這麼想的,是以,就出現了一個記憶體分頁管理。把整個虛拟記憶體和實體記憶體空間切成固定大小的頁片,linux 中,預設這個頁片是 4k。若一個程序需要 256m 的記憶體空間,就把這個空間大小除以 4k,就得到了它的頁片數,就分成這麼多頁。虛拟記憶體中,建立一個頁表,記錄頁資訊,需要的時候就去實體記憶體中擷取,實體記憶體也不需要全部都存放,也可以在用的時候,記憶體再去其他裝置上擷取,因為每次都隻擷取幾 k,量少,速度也會很快。
這個,我們怎麼了解呢?
依然用 excel 工作表舉例,在一個表格中存了很多資料,我們可以根據某列的值進行分組,相同的為一組,那麼,你要找某個資料時,是不是看下它的值,然後,直接找它那一組的資料,再從一組資料中找到你想要的資料,是不是要快很多。
但是,這個分組管理簡單嗎?
可能,想像中簡單,但是實際工程中還是很複雜的。是以,這個頁管理還是很複雜的。感興趣的同學,可以自己再去學習研究。
好了,對于今天講的虛拟記憶體、實體記憶體、swap 分區知識掌握了嗎?