1. 程式人生 > >Linux基礎之虛擬記憶體檔案對映mmap

Linux基礎之虛擬記憶體檔案對映mmap

mmap概念

  mmap是一種記憶體對映檔案的方法,即將一個檔案或者其它物件對映到程序的地址空間,實現檔案磁碟地址和程序虛擬地址空間中一段虛擬地址的一一對映關係
  特點:實現這樣的對映關係後,程序就可以採用指標的方式讀寫操作這一段記憶體,而系統會自動回寫髒頁面到對應的檔案磁碟上,即完成了對檔案的操作而不必再呼叫read,write等系統呼叫函式。相反,核心空間對這段區域的修改也直接反映使用者空間,從而可以實現不同程序間的檔案共享。如下圖所示:
  mmap示意圖

mmap記憶體對映原理

  mmap記憶體對映的實現過程,總的來說可以分為三個階段:

  1. 應用程序啟動對映,在程序的虛擬地址空間中,尋找一段空閒的滿足要求的連續的虛擬地址作為對映區域;
  2. 呼叫系統函式mmap,實現檔案實體地址和程序虛擬地址的一一對映;
  3. 應用程序對對映區域訪問,引發缺頁異常,實現檔案內容到實體記憶體(主存)的拷貝;

mmap優缺點

  1. 只有一次資料拷貝:當發生缺頁異常時,直接將資料從磁碟拷貝到程序的使用者空間,跳過了頁快取。
  2. 實現了使用者空間和核心空間的高效互動方式:兩空間的各自修改操作可以直接反映在對映的區域內,從而被對方空間及時捕捉。
  3. 提供程序間共享記憶體及相互通訊的方式。
      不管是父子程序還是無親緣關係的程序,都可以將自身使用者空間對映到同一個檔案或匿名對映到同一片區域。從而通過各自對對映區域的改動,達到程序間通訊和程序間共享的目的。
      同時,如果程序A和程序B都映射了區域C,當A第一次讀取C時通過缺頁從磁碟複製檔案頁到記憶體中;但當B再讀C的相同頁面時,雖然也會產生缺頁異常,但是不再需要從磁碟中複製檔案過來,而可直接使用已經儲存在記憶體中的檔案資料。

mmap注意點

  1. 對於大檔案而言,記憶體對映比普通IO流要快,小檔案則未必;
  2. 不要經常呼叫MappedByteBuffer.force()方法,這個方法強制作業系統將記憶體中的內容寫入硬碟,所以如果你在每次寫記憶體對映檔案後都呼叫force()方法,你就不能真正從記憶體對映檔案中獲益,而是跟disk IO差不多。
  3. 讀寫記憶體對映檔案是作業系統來負責的,因此,即使你的Java程式在寫入記憶體後就掛掉了,只要作業系統工作正常,資料就會寫入磁碟
  4. 如果電源故障或者主機癱瘓,有可能記憶體對映檔案還沒有寫入磁碟,意味著可能會丟失一些關鍵資料。