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

來源:互聯網
上載者:User

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

關於Linux 虛擬記憶體和實體記憶體的理解。

首先,讓我們看下虛擬記憶體:

第一層理解

1. 每個進程都有自己獨立的4G記憶體空間,各個進程的記憶體空間具有類似的結構

2. 一個新進程建立的時候,將會建立起自己的記憶體空間,此進程的資料,代碼等從磁碟拷貝到自己的進程空間,哪些資料在哪裡,都由進程式控制製表中的task_struct記錄,task_struct中記錄中一條鏈表,記錄中記憶體空間的分配情況,哪些地址有資料,哪些地址無資料,哪些可讀,哪些可寫,都可以通過這個鏈表記錄

3. 每個進程已經分配的記憶體空間,都與對應的磁碟空間映射

問題:

電腦明明沒有那麼多記憶體(n個進程的話就需要n*4G)記憶體

建立一個進程,就要把磁碟上的程式檔案拷貝到進程對應的記憶體中去,對於一個程式對應的多個進程這種情況,浪費記憶體!

第二層理解

1. 每個進程的4G記憶體空間只是虛擬記憶體空間,每次訪問記憶體空間的某個地址,都需要把地址翻譯為實際實體記憶體地址

2. 所有進程共用同一實體記憶體,每個進程只把自己目前需要的虛擬記憶體空間映射並儲存到實體記憶體上。

3. 進程要知道哪些記憶體位址上的資料在實體記憶體上,哪些不在,還有在實體記憶體上的哪裡,需要用頁表來記錄

4.頁表的每一個表項分兩部分,第一部分記錄此頁是否在實體記憶體上,第二部分記錄實體記憶體頁的地址(如果在的話)

5. 當進程訪問某個虛擬位址,去看頁表,如果發現對應的資料不在實體記憶體中,則缺頁異常

6.缺頁異常的處理過程,就是把進程需要的資料從磁碟上拷貝到實體記憶體中,如果記憶體已經滿了,沒有空地方了,那就找一個頁覆蓋,當然如果被覆蓋的頁曾經被修改過,需要將此頁寫回磁碟

總結:

優點:

1.既然每個進程的記憶體空間都是一致而且固定的,所以連結器在連結可執行檔時,可以設定記憶體位址,而不用去管這些資料最終實際的記憶體位址,這是有獨立記憶體空間的好處

2.當不同的進程使用同樣的代碼時,比如庫檔案中的代碼,實體記憶體中可以只儲存一份這樣的代碼,不同的進程只需要把自己的虛擬記憶體映射過去就可以了,節省記憶體

3.在程式需要分配連續的記憶體空間的時候,只需要在虛擬記憶體空間分配連續空間,而不需要實際實體記憶體的連續空間,可以利用片段。

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

補充理解:

虛擬儲存空間涉及三個概念: 虛擬儲存空間,磁碟空間,記憶體空間

可以認為虛擬空間都被映射到了磁碟空間中,(事實上也是按需要映射到磁碟空間上,通過mmap),並且由頁表記錄映射位置,當訪問到某個地址的時候,通過頁表中的有效位,可以得知此資料是否在記憶體中,如果不是,則通過缺頁異常,將磁碟對應的資料拷貝到記憶體中,如果沒有空閑記憶體,則選擇犧牲頁面,替換其他頁面。

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

接下來我們來討論下實體記憶體:

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

1.實體記憶體的核心映射

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

1).高端記憶體不能全部映射到核心空間,也就是說這些實體記憶體沒有對應的線性地址。不過,核心為每個物理頁框都分配了對應的頁框描述符,所有的頁框描述符都儲存在mem_map數組中,因此每個頁框描述符的線性地址都是固定存在的。核心此時可以使用alloc_pages()和alloc_page()來分配高端記憶體,因為這些函數返回頁框描述符的線性地址。

2).核心地址空間的後128MB專門用於映射高端記憶體,否則,沒有線性地址的高端記憶體不能被核心所訪問。這些高端記憶體的核心映射顯然是暫時映射的,否則也只能映射128MB的高端記憶體。當核心需要訪問高端記憶體時就臨時在這個地區進行地址映射,使用完畢之後再用來進行其他高端記憶體的映射。

由於要進行高端記憶體的核心映射,因此直接能夠映射的實體記憶體大小隻有896MB,該值儲存在high_memory中。核心地址空間的線性地址區間如所示:

可以看出,核心採用了三種機制將高端記憶體映射到核心空間:永久核心映射,固定映射和vmalloc機制。

2.實體記憶體管理機制

基於實體記憶體在核心空間中的映射原理,實體記憶體的管理方式也有所不同。核心中實體記憶體的管理機制主要有夥伴演算法,slab快取和vmalloc機制。其中夥伴演算法和slab快取都在實體記憶體映射區分配實體記憶體,而vmalloc機制則在高端記憶體映射區分配實體記憶體。

夥伴演算法

夥伴演算法負責大塊連續實體記憶體的分配和釋放,以頁框為基本單位。該機制可以避免外部片段。

per-CPU頁框快取

核心經常請求和釋放單個頁框,該緩衝包含預先分配的頁框,用於滿足本地CPU發出的單一頁框請求。

slab緩衝

slab緩衝負責小塊實體記憶體的分配,並且它也作為快取,主要針對核心中經常分配並釋放的對象。

vmalloc機制

vmalloc機制使得核心通過連續的線性地址來訪問非連續的物理頁框,這樣可以最大限度的使用高端實體記憶體。

3.實體記憶體的分配

核心發出記憶體申請的請求時,根據核心功能調用介面將啟用不同的記憶體 Clerk。

3.1 分區頁框分配器

分區頁框分配器 (zoned page frame allocator) ,處理對連續頁框的記憶體配置請求。分區頁框管理器分為兩大部分:前端的管理區分配器和夥伴系統,如:

管理區分配器負責搜尋一個能滿足請求頁框塊大小的管理區。在每個管理區中,具體的頁框分配工作由夥伴系統負責。為了達到更好的系統效能,單個頁框的申請工作直接通過per-CPU頁框快取完成。該分配器通過幾個函數和宏來請求頁框,它們之間的封裝關係如所示。

這些函數和宏將核心的分配函數__alloc_pages_nodemask()封裝,形成滿足不同分配需求的分配函數。其中,alloc_pages()系列函數返回實體記憶體首頁框描述符,__get_free_pages()系列函數返回記憶體的線性地址。      3.2 slab分配器

slab 分配器最初是為瞭解決實體記憶體的內部片段而提出的,它將核心中常用的資料結構看做對象。slab分配器為每一種對象建立快取。核心對該對象的分配和釋放均是在這塊快取中操作。一種對象的slab分配器結構圖如下:

可以看到每種對象的快取是由若干個slab組成,每個slab是由若干個頁框組成的。雖然slab分配器可以分配比單個頁框更小的記憶體塊,但它所需的所有記憶體都是通過夥伴演算法分配的。slab快取分專用緩衝和通用緩衝。專用緩衝是對特定的對象,比如為記憶體描述符建立快取。通用緩衝則是針對一般情況,適合分配任意大小的實體記憶體,其介面即為kmalloc()。      3.3 非連續記憶體區記憶體的分配

核心通過vmalloc()來申請非連續的實體記憶體,若申請成功,該函數返回連續記憶體區的起始地址,否則,返回NULL。vmalloc()和kmalloc()申請的記憶體有所不同,kmalloc()所申請記憶體的線性地址與物理地址都是連續的,而vmalloc()所申請的記憶體線性地址連續而物理地址則是離散的,兩個地址之間通過核心頁表進行映射。vmalloc()的工作方式理解起來很簡單:       

1).尋找一個新的連續線性地址空間;       

2).依次分配一組非連續的頁框;       

3).為線性地址空間和非連續頁框建立映射關係,即修改核心頁表;

vmalloc()的記憶體配置原理與使用者態的記憶體配置相似,都是通過連續的虛擬記憶體來訪問離散的實體記憶體,並且虛擬位址和物理地址之間是通過頁表進行串連的,通過這種方式可以有效使用實體記憶體。但是應該注意的是,vmalloc()申請實體記憶體時是立即分配的,因為核心認為這��記憶體配置請求是正當而且緊急的;相反,使用者態有記憶體請求時,核心總是儘可能的延後,畢竟使用者態跟核心態不在一個特權級。

本文永久更新連結地址:

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.