1. 程式人生 > >Linux 虛擬記憶體機制

Linux 虛擬記憶體機制

華為面試官問了我一個問題就是關於Linux虛擬記憶體機制,雖然我多少是回答上來,感覺好久沒看作業系統的我是時候將其拿起來重溫一遍 。


  • 每個程序都有自己獨立的4G記憶體空間,各個程序的記憶體空間具有類似的結構。
  • Linux記憶體管理採用的是頁式管理,使用的是多級頁表,動態地址轉換機構與主存、輔存共同實現虛擬記憶體
  • 一個新程序建立的時候,將會建立起自己的記憶體空間,此程序的資料,程式碼等從磁碟拷貝到自己的程序空間,哪些資料在哪裡,都由程序控制表中的task_struct記錄,task_struct中記錄中一條連結串列,記錄中記憶體空間的分配情況,哪些地址有資料,哪些地址無資料,哪些可讀,哪些可寫,都可以通過這個連結串列記錄
  • 每個程序已經分配的記憶體空間,都與對應的磁碟空間對映
    memory_2

每個程式都能看到一片完整連續的地址空間,這些空間並沒有直接關聯到實體記憶體,而是作業系統提供了記憶體的一種抽象概念,使得每個程序都有一個連續完整的地址空間,在程式的執行過程,再完成虛擬地址到實體地址的轉換。我們同樣知道,程序的地址空間是分段的,存在所謂的資料段,程式碼段,bbs段,堆,棧等等。每個段都有特定的作用。
同時計算機沒有那麼多的記憶體(n個程序就需要對應n*4G記憶體),建立一個程序,就要把磁碟上的程式檔案拷貝到程序對應的記憶體中去,對於有一個程式對應多個程序這種情況,浪費記憶體。

深入理解

  • 1.每個程序的4G記憶體空間只是虛擬記憶體空間,每次訪問記憶體空間的某個地址,都需要把地址翻譯為實際實體地址
  • 2.所有程序共享同一實體記憶體,每個程序只把自己目前需要的虛擬記憶體空間對映並存儲到實體記憶體上
  • 3.程序要知道哪些記憶體地址上的資料在實體記憶體上,哪些不在,還有在實體記憶體上的哪裡,需要頁表記錄
  • 4.頁表的每一個表項分為兩部分,第一部分記錄此頁是否在實體記憶體上,第二部分記錄實體記憶體的地址
  • 5.當程序訪問某個虛擬地址,去檢視頁表,如果對應的資料不在實體記憶體中,,則缺頁異常
  • 6.缺頁異常的處理過程,就是把程序需要的資料從磁碟拷貝到實體記憶體中,如果記憶體已經滿了 ,沒有空地方,那就找一個頁進行覆蓋,當然如果被覆蓋的頁曾經被修改過,需要將此頁寫回磁碟

小結

優點:

1.竟然每個程序的記憶體空間都是一致而且固定的,所以連結器在連結執行檔案時,可以設定記憶體地址,而 不用去管這些資料最終實際的記憶體地址,這是有獨立記憶體 空間的好處
2.當不同的程序使用同樣的程式碼時,比如庫檔案中的程式碼,實體記憶體中可以只儲存一份這樣的程式碼,不同的程序只需要把自己的虛擬記憶體對映過去就可以了,節省記憶體
3.在程式需要分配連續的記憶體空間的時候,只需要在虛擬記憶體空間分配連續空間,而不需要實際實體記憶體的連續空間,可以利用碎片。

另外,事實上,在每個程序建立載入時,核心只是為程序“建立”了虛擬記憶體的佈局,具體就是初始化程序控制表中記憶體相關的連結串列,實際上並不立即就把虛擬記憶體對應位置的程式資料和程式碼(比如.text .data段)拷貝到實體記憶體中,只是建立好虛擬記憶體和磁碟檔案之間的對映就好(叫做儲存器對映),等到執行到對應的程式時,才會通過缺頁異常,來拷貝資料。還有程序執行過程中,要動態分配記憶體,比如malloc時,也只是分配了虛擬記憶體,即為這塊虛擬記憶體對應的頁表項做相應設定,當程序真正訪問到此資料時,才引發缺頁異常

關於mmap

mmap是用來建立從虛擬空間到磁碟空間的對映的,可以將一個虛擬空間地址對映磁碟檔案上,當不設定這個地址的時候,則由系統自動設定,函式返回對應的記憶體地址(虛擬地址),當訪問這個地址的時候,就需要把磁碟上的內容拷貝到記憶體了,然後就可以讀或者寫,最後通過manmap可以將記憶體上的資料換回到磁碟,也就是解除虛擬空間和記憶體空間的對映,這樣也是一種程序共享資料的方法共享記憶體

關於動態申請空間

在核心態申請記憶體比使用者態申請記憶體更為直接,他沒有采用使用者態那種延遲分配記憶體技術,核心認為一旦有核心函式申請記憶體,那麼就必須立刻滿足該申請記憶體的請求,並且這個請求一定是正確合理的,相反,對於使用者動態申請記憶體的請求,核心總是儘量延後分配實體記憶體,使用者總是先獲得一個 虛擬記憶體區的使用權,最終通過缺頁異常獲得一塊真正的實體記憶體。

實體記憶體的核心對映

IA32架構中核心虛擬地址空間只有1GB大小(從3GB到4GB),因此可以直接將1GB大小的實體記憶體(即常規記憶體)對映到核心地址空間,但超出1GB大小的實體記憶體(即高階記憶體)就不能對映到核心空間。為此,核心採取了下面的方法使得核心可以使用所有的實體記憶體。

  • 高階記憶體不能全部對映到核心空間,也就是說這些實體記憶體沒有對應的線性地址。不過,核心為每個物理頁框都分配了對應的頁框描述符,所有的頁框描述符都儲存在mem_map陣列中,因此每個頁框描述符的線性地址都是固定存在的。核心此時可以使用alloc_pages()和alloc_page()來分配高階記憶體,因為這些函式返回頁框描述符的線性地址。
  • 核心地址空間的後128MB專門用於對映高階記憶體,否則,沒有線性地址的高階記憶體不能被核心所訪問。這些高階記憶體的核心對映顯然是暫時對映的,否則也只能對映128MB的高階記憶體。當核心需要訪問高階記憶體時就臨時在這個區域進行地址對映,使用完畢之後再用來進行其他高階記憶體的對映。

virtual_memory

核心採用了三種機制將高階記憶體對映到核心空間:永久核心對映,固定對映和vmalloc機制。

相關推薦

Linux 虛擬記憶體機制

華為面試官問了我一個問題就是關於Linux虛擬記憶體機制,雖然我多少是回答上來,感覺好久沒看作業系統的我是時候將其拿起來重溫一遍 。 每個程序都有自己獨立的4G記憶體空間,各個程序的記憶體空間具有類似的結構。 Linux記憶體管理採用的是頁式管理,

Linux虛擬記憶體(swap)調優篇-swappiness引數

                     Linux虛擬記憶體(swap)調優篇                                            作者:尹正傑 版權宣告:原創作品,謝絕轉載!否則將追究法律責任。     swappiness的值的大小對如何使用swap分

Linux 虛擬記憶體和實體記憶體的理解 (轉載)

轉載於:https://www.cnblogs.com/panchanggui/p/9288389.html 關於Linux 虛擬記憶體和實體記憶體的理解。 首先,讓我們看下虛擬記憶體: 第一層理解 每個程序都有自己獨立的4G記憶體空間,各個程序的記憶體空間具有類似的結構

簡述Linux虛擬記憶體管理

原文地址:https://cloud.tencent.com/ developer/article/1157420 虛擬儲存 虛擬儲存(virtual memory, VM)的基本思想是: 維護一個虛擬的邏輯記憶體機制(通常比實體記憶體大得多), 程序都基於這個虛擬記憶體, 在

淺談下linux記憶體機制

Linux的記憶體管理採取的是分頁存取機制,為了保證實體記憶體能得到充分的利用,核心會在適當的時候將實體記憶體中不經常使用的資料塊自動交換到虛擬記憶體中,而將經常使用的資訊保留到實體記憶體。 各項指標: --Mem total1 實體記憶體總數: 3832M use

linux 虛擬記憶體初識

一個執行程式時,虛擬記憶體技術如何運作: 虛擬記憶體空間的大小是由程式計數器的定址能力來決定的 採用虛擬技術,就存在兩個記憶體空間: 虛擬記憶體空間,其中的地址叫做“虛擬地址” 實體記憶體空間,其中的地址叫做“實體地址” 處理器運算器、應用程式設計人員

解決linux虛擬記憶體不夠用的方法

虛擬記憶體 (swap) 虛擬記憶體就是將硬碟規劃出一個區 間,讓記憶體的資料可以經由硬碟來讀取。 建立和擴大swap: l  建立虛擬記憶體裝置 第一種正規的方法是『直接再加一硬碟,並且將其中某個分割槽規 劃為 swap 的 filesystem 』:思路是:

紅黑樹在Linux虛擬記憶體區域管理中的應用

參考資料:http://wenku.baidu.com/view/f0795f8783d049649b66586f.html Linux核心中每一個使用者程序都可以訪問4GB的線性虛空間,為了能表達真正被程序使用的虛擬記憶體空間,Linux定義了虛擬儲存區域(virtua

Linux虛擬記憶體系統常用引數說明

  預設值是100,核心會根據pagecache和swapcache的回收情況,讓dentry和inode cache的記憶體佔用量保持在一個相對公平的百分比上。減小vfs_cache_pressure會讓核心更傾向於保留dentry和inode cache。當vfs_cache_pressure等於0,在記

Linux 虛擬記憶體和實體記憶體的管理

MMU進行虛擬地址到物理轉換的時候,並不是一個個地址轉換的,而是一段段地址轉換。 轉換的單位: section  段   1MB    ----> u-boot large page  大頁   64KB small page  小頁    4kB   ----> linux內,page=4KB

計算機底層知識拾遺(一)理解虛擬記憶體機制

這個系列會總結計算機,網路相關的一些重要的底層原理。很多底層原理大家上學的時候都學過,但是在學校的時候大部分的同學都是為了應付考試而學習,過幾天全忘了。隨著工作的時間越久,越體會到這些基礎知識的重要性。做技術和練武功一樣,當你到了一定的階段,也會遇到一個瓶頸,突破了你的眼界

Linux虛擬記憶體管理(一)

分頁機制 虛擬記憶體—— 計算機的記憶體容量有限,而某些程序執行所需的記憶體空間可能超過記憶體總容量,因而出現機器記憶體容納不下該程序所有程式碼、資料和堆疊而只能容納其中一部分的情況。 虛擬儲存的基本思想:一個程序的程式碼、資料、堆疊的總容量可能超過可用實

Linux虛擬記憶體的作用

要深入瞭解linux記憶體執行機制,需要知道下面提到的幾個方面:首先,Linux系統會不時的進行頁面交換操作,以保持儘可能多的空閒實體記憶體,即使並沒有什麼事情需要記憶體,Linux也會交換出暫時不用的記憶體頁面。這可以避免等待交換所需的時間。 其次,linux進行頁面

Linux虛擬記憶體對映之brk/sbrk,map/munmap

一.關於虛擬記憶體          問題:                    一個程式不能訪問另外一個程式的地址指向的空間.          理解:                    1.每個程式的開始地址ox8048000(?可由objdump 反彙編得到)

Linux虛擬記憶體組織結構淺析(一)

為了支援NUMA,Linux將實體記憶體劃分成不同的節點(node),節點用結構體pg_data_t表示,以上圖為例,圖中每個CPU的本地實體記憶體都稱為一個節點;即使在UMA結構中也有節點的概念,此時系統中就只有一個節點;系統中的多個節點被連線起來儲存在一個稱為pgdat_list的連結串列上。每個節點又被

Linux虛擬記憶體

Linux採用虛擬段頁式儲存方式來管理記憶體,程式的基本邏輯儲存單元,也可以說是程式段。Linux中有四個段,程式碼段,資料段,BSS段,堆疊段。虛擬地址從低到高依次是:程式碼段,資料段,BSS段,堆疊段。其中程式碼段為程式本身(二進位制指令),資料段為程式碼中

linux下的虛擬記憶體和分頁分段機制

前言:由於計算機的記憶體是有限的,比0到2的32次方就是對應4G,這時候作業系統就引入了虛擬記憶體這一個概念, 1,首先可以從程式的編譯下手,對於java或者c++而言,程式在編譯的時候需要記憶體,但是此時程式並沒有在真的物理機上執行著,所以就引入虛擬記憶體這

Linux分頁機制之概述--Linux記憶體管理(六)

1 分頁機制 在虛擬記憶體中,頁表是個對映表的概念, 即從程序能理解的線性地址(linear address)對映到儲存器上的實體地址(phisical address). 很顯然,這個頁表是需要常駐記憶體的東西, 以應對頻繁的查詢對映需要(實際上,現代支援VM的處理器都有一個叫TLB的硬體級頁表快取部件

深入Linux核心架構——程序虛擬記憶體

逆向對映(reverse mapping)技術有助於從虛擬記憶體頁跟蹤到對應的實體記憶體頁; 缺頁處理(page fault handling)允許從塊裝置按需讀取資料填充虛擬地址空間。 一、簡介 使用者虛擬地址空間的管理比核心地址空間的管理複雜: 每個應用程式都有自身的地址空間,與

Linux下的RAM,ROM,虛擬記憶體介紹

其實RAM就是快取記憶體,通電就具有記憶功能,斷電就失去,也就是執行記憶體,就是用來存放臨時檔案,而“記憶體”就是RAM的 一種物理硬體,廣義來說兩者也可以說是同一概念。而虛擬記憶體是系統利用硬碟分出來的具有輔助記憶體工作的虛擬RAM,不是 硬體,但又依靠硬碟。 簡單的說 RAM是你一般