「Golang」mmap “像使用內存一樣操作文件”

mmap並不是什麼新技術,早在4.2BSD的系統說明中就已經出現了mmap相關函數,並且mmap屬於POSIX標準。在一眾開源軟件中都使用到了mmap,如Etcd、InfluxDB、RocketMQ等。

想要理解MMAP,就不得不說到 虛擬內存(Virtual Memory,VM)。

虛擬內存 VM

虛擬內存是現代操作系統重要的一部分,它具備3個重要的能力:

  • 把內存用做硬盤的高速緩存快速交換數據
  • 為每個進程提供一致的地址空間,簡化內存管理
  • 保護每個進程的地址空間不被其它進程破壞

為了讓每個進程都有一致的地址空間,引入虛擬內存空間的概念,由虛擬內存映射至物理內存,進程就無需關心數據存放在物理內存哪個位置。CPU通過虛擬地址訪問內存,由CPU的內存管理單元(Memory Management Unit,MMU)負責將虛擬地址翻譯為物理地址。


「Golang」mmap “像使用內存一樣操作文件”

虛擬地址

虛擬內存按一定大小分割為頁——虛擬頁(Virtual Page,VP)。n位虛擬地址分為兩部分,p位虛擬地址偏移量和(n-p)位的虛擬頁號(Virtual Page Number,VPN),p由虛擬頁大小決定。為了將虛擬地址翻譯為物理地址,每個進程都有獨立的 頁表(Page Table,PT),頁表條目(Page Table Entry,PTE) 組成的數組,每條PTE記錄了虛擬頁號 -> 物理頁號(Physical Page Number,PPN)/硬盤地址 的映射關係,就好像字典的目錄一樣。MMU翻譯時會讀取頁表,由操作系統負責維護頁表內容。


「Golang」mmap “像使用內存一樣操作文件”

mmap() 就是將虛擬地址映射至硬盤上的對象,當CPU首次請求這部分虛擬地址時,發現有效位為0即缺頁,觸發 頁面調度(paging),將頁從磁盤換入內存。如果頁被修改則變為髒頁,操作系統控制將髒頁寫回硬盤。

Golang

Golang使用系統調用的時候,需要注意 syscall 已經被棄用,替代的庫為 golang.org/x/sys


「Golang」mmap “像使用內存一樣操作文件”

demo(沒有處理任何error)


「Golang」mmap “像使用內存一樣操作文件”

hexdump文件內容


分享到:


相關文章: