1. 程式人生 > >記憶體對映機制(mmap)

記憶體對映機制(mmap)

  • 當CPU讀取資料時,是由記憶體管理單元(MMU)管理的。MMU位於CPU與實體記憶體之間,它包含從虛地址向實體記憶體地址轉化的對映資訊。當CPU引用一個記憶體位置時,MMU決定哪些頁需要駐留(通常通過移位或遮蔽地址的某些位)以及轉化虛擬頁號到物理頁號。
    在這裡插入圖片描述
  • 當某個程序讀取磁碟上的資料時,程序要求其緩衝通過read()系統呼叫填滿,這個系統呼叫導致核心想磁碟控制硬體發出一條命令要從磁盤獲取資料。磁碟控制器通過DMA直接將資料寫入核心的記憶體緩衝區,不需要CPU協助。當請求read()操作時,一旦磁碟控制器完成了快取的填寫,核心從核心空間的臨時快取拷貝資料到程序指定的快取中。
  • 使用者空間是常規程序所在的區域,該區域執行的程式碼不能直接訪問硬體裝置。核心空間是作業系統所在的區域,該區域可以與裝置控制器通訊,控制使用者區域程序的執行狀態。
    在這裡插入圖片描述
  • 記憶體對映檔案技術是作業系統提供的一種新的檔案資料存取機制,利用記憶體對映檔案技術,系統可以在記憶體空間中為檔案保留一部分空間,並將檔案對映到這塊保留空間,一旦檔案被對映後,作業系統將管理頁對映緩衝以及高速緩衝等任務,而不需要呼叫分配、釋放記憶體塊和檔案輸入/輸出的API函式,也不需要自己提供任何緩衝演算法。
  • 使用記憶體對映檔案處理儲存於磁碟上的檔案時,將不必再對檔案執行I/O 操作,這意味著在對檔案進行處理時將不必再為檔案申請並分配快取,所有的檔案快取操作均由系統直接管理,由於取消了將檔案資料載入到記憶體、資料從記憶體到檔案的回寫以及釋放記憶體塊等步驟,使得記憶體對映檔案在處理大資料量的檔案時能起到相當重要的作用。

linux 記憶體對映機制

void  *mmap(void  *start,  size_t length,  int prot,  int flags,  int fd,  off_t offsize)
int  munmap(void *start,   size_t length)

mmap將一個檔案或者其它物件對映進記憶體。檔案被對映到多個頁上,如果檔案的大小不是所有頁的大小之和,最後一個頁不被使用的空間將會清零。 munmap執行相反的操作,刪除特定地址區域的物件對映。
在這裡插入圖片描述

  • 返回說明:

成功執行時,mmap()返回被對映區的指標,munmap()返回0。失敗時,mmap()返回MAP_FAILED(其為(void*)-1),munmap 返回-1。

  • 引數:

start:對映區的開始地址。
length:對映區的長度。
prot:對映區域的保護方式。可以為以下幾種方式的組合


    PROT_EXEC //頁內容可以被執行
    PROT_READ //頁內容可以被讀取
    PROT_WRITE //頁可以被寫入
    PROT_NONE //頁不可訪問

flags:指定對映物件的型別,對映選項和對映頁是否可以共享。它的值可以是一個或者多個以下位的組合體

MAP_FIXED //使用指定的對映起始地址,如果由 start和len 引數指定的記憶體區重疊於現存的對映空間,重疊部分將會被丟棄。如果指定的起始地址不可用,操作將會失敗。並且起始地址必須落在頁的邊界上。
MAP_SHARED //與其它所有對映這個物件的程序共享對映空間。對共享區的寫入,相當於輸出到檔案。直到 msync()或者munmap() 被呼叫,檔案實際上不會被更新。
MAP_PRIVATE //建立一個寫入時拷貝的私有對映。記憶體區域的寫入不會影響到原檔案。這個標誌和以上標誌是互斥的,只能使用其中一個。
MAP_DENYWRITE //這個標誌被忽略。
MAP_EXECUTABLE //同上
MAP_NORESERVE //不要為這個對映保留交換空間。當交換空間被保留,對對映區修改的可能會得到保證。當交換空間不被保留,同時記憶體不足,對對映區的修改會引起段違例訊號。
MAP_LOCKED //鎖定對映區的頁面,從而防止頁面被交換出記憶體。
MAP_GROWSDOWN //用於堆疊,告訴核心VM系統,對映區可以向下擴充套件。
MAP_ANONYMOUS //匿名對映,對映區不與任何檔案關聯。
MAP_ANON //MAP_ANONYMOUS 的別稱,不再被使用。
MAP_FILE //相容標誌,被忽略。
MAP_32BIT //將對映區放在程序地址空間的低 2GB,MAP_FIXED 指定時會被忽略。當前這個標誌只在 x86-64平臺上得到支援。
MAP_POPULATE //為檔案對映通過預讀的方式準備好頁表。隨後對對映區的訪問不會被頁違例阻塞。
MAP_NONBLOCK //僅和MAP_POPULATE 一起使用時才有意義。不執行預讀,只為已存在於記憶體中的頁面建立頁表入口。

fd:有效的檔案描述詞。
offset:被對映物件內容的起點

轉載於:https://blog.csdn.net/aspirinvagrant/article/details/18991263