linux mmap匿名映射的作用是什麼?

mmap可以映射普通文件和匿名文件。匿名文件映射會將一個內核創建的全為進位零文件映射到虛擬內存中。這個操作有什麼應用場景?


malloc有的空間用brk處理,有的用mmap處理。我這麼說明白么?


匿名用於父子進程通信。避免被其他程序共享。


這再次深刻的提醒了你:內存是外存的緩存,而linux一切外存都用「文件」作為驅動程序的讀寫操作的抽象模型。

所以,linux里一切用戶態內存頁都應該是「某個文件」的緩存,即使這塊內存你不把它用來做外存的緩存而是用於臨時存放某些中間結果(你可以用下top命令看io緩存的內存開銷佔用,這些就是給「真正的」外存做緩存的開銷)。


malloc的實現,它有一個chunk倉庫管理128位元組以下的小塊(chunk倉庫類似鏈表數組,)。之所以有chunk倉庫是因為為了避免多次系統調用,快速獲取內存塊,因為從用戶態到內核態的轉換很耗時的(改變cs,ds,ss,各種參數壓棧等等),而有了chunk倉庫可以直接在用戶態獲取內存塊,chunk倉庫類似鏈表數組,其塊大小由2的n次方構成,最大的塊是128位元組.

malloc如果分配超過了128位元組將調用brk系統調用(改變堆界限,同時創建vma)

如果malloc分配超大內存(具體是多少忘了),那就直接mmap匿名映射了創建vma結構。


mmap的使用肯定不是僅僅為了「給我一片可以讀寫的內存」這樣基礎的功能,而是某些特定情況下必須要直接操作物理內存的情況。

在嵌入式領域,mmap可以將外設寄存器的地址(物理地址),映射到用戶內存空間。實現在用戶態下操作寄存器,進而實現用戶態下驅動程序的作用


現在glibc里malloc的實現,主要通過三種方法分配內存給用戶層。

1. 內部管理的內存塊鏈表。大小滿足應用層分配請求時使用。好處是不需要系統調用,在用戶態實現。

2. brk系統調用。當malloc內部內存不夠用,需要向內核申請內存。brk系統調用增大堆頂位置,但是只是虛擬內存。真正使用時會page fault進而真正得到內存。

3. mmap系統調用。malloc實現有一個問題是只有當堆頂空閑內存區大於128K,內存才真正free還給內核。mmap(匿名映射)會在堆頂與棧底之間的shared libs、files區域給應用一個線性區,也是虛擬內存。好處是munmap的時候,內存是真的還給內核。

malloc希望頻繁申請而量小的請求能夠在用戶態完成,也就是方法1。

在malloc里,對於brk和mmap,默認超過128K用mmap,否則用brk。

Brk獲得的內存可以給方法1復用,而mmap只能應用自己管理。頻繁的mmap和munmap系統調用、用戶態與內核態切換以及pagefault開銷是很大的。

有問題歡迎指出。


可以這麼理解把。真正的分配內存跟釋放內存需要調用操作系統mmap跟munmap。而malloc跟free只是用戶態的庫函數,malloc可能只是原先已通過mmap分配一大塊內存中再分一部分沒使用的內存給你,free可能只是將這部分內存標記為沒有使用,供下次malloc再使用,並不會實際釋放內存。這跟malloc跟free的具體實現有關。


推薦閱讀:

segfault at xxx的地址是物理地址還是線性地址,objdump出來的呢?
Linux的啟動過程中,滿足什麼條件可以不用initramfs而直接掛載/?
ELF文件裡面section的虛擬地址是如何在鏈接(link)時確定的?

TAG:操作系統 | Linux內核 |