mmap學習


內存頁:

Linux是以頁為單位來管理物理內存的,一頁大小一般等於4096字節。頁容量越大,系統中可能存在的內存碎片就越多。

mmap將一個磁盤上的文件或者對象映射進內存。文件被映射到多個頁上,如果文件的大小不是所有頁的大小之和,最后一個頁不被使用的空間將會清零。

當使用mmap映射文件到進程后,就可以直接操作這段虛擬地址進行文件的讀寫等操作,不必再調用read,write等系統調用。

采用共享內存通信的一個顯而易見的好處是效率高,因為進程可以直接讀寫內存,而不需要任何數據的拷貝。比如像管道和消息隊列,需要在內核和用戶空間進行四次的數據拷貝。

mmap的系統操作有兩個:

#include <sys/mman.h>

void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);

int munmap(void *start, size_t length);

第一個函數mmap,將文件描述符fd中的內容放到內存start --- ( start+ length) 的空間中。

port: 期望的內存保護方式,比如內存可讀/可寫/可執行,但是不能與文件的打開模式沖突。就是只能是文件權限的子集。

flag: 指定映射對象的類型

fd: 被映射的文件描述符。

第二個函數munmap,解除一個映射關系。

這兩個函數的說明文檔在:

http://man7.org/linux/man-pages/man2/mmap.2.html

例子

比如這個例子是php的apc使用了mmap:

#strace -p `cat /var/run/httpd.pid`

open("/var/www/html/apc_load.php", O_RDONLY) = 13

...

mmap2(NULL, 31457280, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, 1232, 0) = 0xb5ce7000

...

nanosleep({3600, 0},

mmap2() 系統調用執行的操作幾乎與mmap(2) 一樣,唯一的區別在於最后一個參數給出的在文件中的偏移是以4096-字節為單位。

這個mmap就在內存中空出30M的空間做內存映射

php的apc緩存加速

php的apc大致原理是將php的opcode(php的操作碼)使用mmap映射(就是復制)到共享內存中,然后下次用戶再訪問調用php訪問,就可以直接去共享內存中讀取,而不需要再到磁盤上讀取了。

當然當php文件更新的時候,opcode也會自動失效(有檢測機制)。

參考文章:

http://blog.chinaunix.net/uid-26669729-id-3077015.html

http://www.perfgeeks.com/?p=298

http://www.searchtb.com/2010/12/php-opcode-cache.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM