linux內存管理初學

虛擬內存模型

Linux 內核本身並不運行在虛擬空間中,其使用的是物理尋址模式。

    物理內存被分割爲界面,一個內存頁面的大小由PAGE_SIZE宏決定。

虛擬地址空間的方式使程序員可以將巨大的結構用於連續的地址,而不必考慮物理內存上的限制。

線性地址到物理地址

線性地址需要由處理器或者一個單獨的MMU轉換爲物理地址,轉換方式如下:

842584-20151122214843155-564971340.jpg

 

解析的方式爲:

1.用線性地址中的第一個位段爲下標可以在頁面目錄中找的一個表項,這個表項指向某個中間目錄。

2.用線性地址中的第二個位段爲下標可以在該中間目錄中找到一個表項,該表項指向某個頁面表。

3.用線性地址中的第三個位段爲下標可以在該頁面表中找到一個表項,該表項指向物理內存中的某個物理頁面。

4.用線性地址中的第四個位段爲偏移量,將次偏移量與該物理頁面的基地址相加便得到相應的物理地址。

注 : TLB中存的是頁面目錄基地址。

 

而內核空間的線性地址解析成物理地址的過程相對簡單,因爲系統本身要爲自己維護一張頁表是一件很噁心的事情,所以內核空間的地址和物理地址是簡單的直接映射,0xc0000000就是兩者的偏移量。

也就是說:對於系統空間,給定一個虛地址x,其物理地址是x中減去PAGE_OFFSET;相應的,給定一個物理地址x,其虛地址是x+PAGE_OFFSET

當然,不能全部用來做簡單映射,因爲如果內存有4G,那麼如果直接全部做簡單映射,那麼內核只能訪問0-1G的內存了,所以內核中實際是前896M做直接映射,剩下的用來做vmalloc申請區,永久內存映射區,固定映射區等。如下圖:

842584-20151122214852780-181895543.jpg

 

 

 

幾個創建進程函數

Fork子進程只是複製父進程的資源,兩進程內存空間獨立,運行時並行。爲了降低運行時的開銷,對資源採用寫時複製(也就是fork並不直接拷貝資源,只是當發生寫入的時候才完成拷貝)。

Vfork共享地址空間,創建後進程父進程阻塞直到子進程結束。

Clone有參數,可以有選擇的將數據複製給子進程,剩下的通過指針共享。

幾個申請內存的函數的區別

1. kmallocvmalloc分配內核空間的內存,malloc分配用戶空間的內存。

2. kmalloc物理連續,vmalloc虛擬地址連續。

3. kmalloc能分配的空間大小有限,vmallocmalloc能分配的較大。

4. 內存在被DMA時需要物理連續。

5. Kmalloc更快

6. Kmalloc使用slab機制,返回地址之後就已經對應實際內存了。

缺頁中斷

如果MMU處理器不能訪問一個頁面,它將產生一個缺頁中斷。Linux缺頁異常程序必須能區分由編程引起的以及由引用屬於地址空間還未分配物理頁框的頁引起的異常,如果合法則分配新的頁框。

每個進程都有自己的頁表。

頁面管理

請求換頁

    爲了節省內存,操作系統只會加載那些正在被執行程序使用的虛擬頁面。比如,某個數據庫程序可能要對某個數據庫進行查詢操作,此時並不是數據庫的所有內容都要加載到內存中去,而只加載那些要用的部分。這種僅將要訪問的界面載入的技術叫請求換頁

 

當進程試圖訪問不在內存中的虛擬地址時,將觸發一個缺頁中斷

 

如果出錯的地址是無效的,比如進行了一個隨機的寫操作,則操作系統終止此進程,此進程的出錯不會影響其他進程。

 

如果出錯的地址是有效的,但是它訪問的頁面不在內存中。則操作系統必須將此界面從磁盤映像中讀出來。訪盤時間比較長,進程必須等待一段時間直到頁面被取出來。取過來的頁面放在一個空閒的物理頁框之中,同時此進程的頁表中將添加對應此虛擬頁面框號的入口。然後進程從出錯的地方從新開始運行。

 

交換

如果進程需要把一個虛擬頁面調入物理內存而正好系統沒有空閒的物理頁面,操作系統必須丟棄系統中某些頁面來爲之騰出空間。

 

如果那些從物理內存中丟棄出來的界面來自於磁盤上的可執行文件或者數據文件,並且沒有修改過則不需要保存那些界面。當進程再次需要此頁面時,直接從可執行文件或者數據文件中讀出即可。

 

但是如果頁面被修改過,則系統必須將其保存以備再次訪問。這種界面叫做dirty界面。當從內存中移出來的時候,他們必須保存在叫做交換文件的特殊文件中。相對於cpu和內存的速度,訪問交換文件的速度很慢,所以操作系統必須衡量好將那些dirty頁交換或將其保留在內存中做出一個選擇。

 

如果丟棄頁面的算法選擇的不夠好,則可能不斷地出現頁面被寫入又被從磁盤中讀回的情況使效率變低。Linux使用最近最少使用(LRU)頁面衰老算法來公平的選擇將要從系統中拋棄的頁面。這種算法爲每個頁面設置一個年齡,它隨頁面訪問次數而變化。頁面被訪問的次數越多則越年輕,相反則衰老。

 

Linux高速緩衝

緩衝區高速緩衝(buffer cache

     緩衝區高速緩衝包含了由塊設備使用的數據緩衝區。這些緩衝區包含了從設備中讀取的數據塊或寫入設備的數據塊。如果數據能夠在緩衝區高速緩衝中找到,則系統沒有必要在物理塊設備上進行實際的讀操作。

頁面高速緩衝(page cache

頁面高速緩衝是頁面I/O操作訪問數據所使用的磁盤高速緩存。我們在文件系統會看到,read()write()mmap()系統調用對常規文件的訪問都是通過頁面高速緩存來完成的。

    緩衝區高速緩存和頁面高速緩存的區別:緩衝區高速緩存是塊設備的cache,頁面高速緩衝是用來做文件系統的cache,也就是它直接記憶我們打開的文件(例如使用兩次man命令,可以明顯感覺第二次更快)。

交換高速緩衝(swap cache

就是交換空間在內存中的緩存。當寫入交換空間的文件並沒有被再次修改,那麼下次再丟棄他的時候就不需要再次寫入交換空間,這個就是通過swap cache來做的。

 

 

注意:

使用top命令會發現有buffercache的概念:

Buffer:簡單的說是要被寫入磁盤的,磁盤和主存的速度不一,所以需要緩衝區做一箇中間層,寫入數據的話先寫入緩衝區,這樣的話寫入的進程沒有必要陷入等待。

Cache(非CPU和主存件的cache):簡單的說就是從磁盤讀入的,存儲在cache裏以備後面再次使用。經常被用在磁盤I/O請求上,如一個文件被訪問,則其將被放入cache中,以備以後再有進程訪問。

 

Cachebuffer都是需要佔用內存的。

 

原文:

A buffer is something that has yet to be "written" to disk. A cache is something that has been "read" from the disk and stored for later use.





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章