天天看點

mmap學習記憶體頁:mmap的系統操作有兩個:例子php的apc緩存加速

Linux是以頁為機關來管理實體記憶體的,一頁大小一般等于4096位元組。頁容量越大,系統中可能存在的記憶體碎片就越多。

mmap将一個磁盤上的檔案或者對象映射進記憶體。檔案被映射到多個頁上,如果檔案的大小不是所有頁的大小之和,最後一個頁不被使用的空間将會清零。

當使用mmap映射檔案到程序後,就可以直接操作這段虛拟位址進行檔案的讀寫等操作,不必再調用read,write等系統調用。

采用共享記憶體通信的一個顯而易見的好處是效率高,因為程序可以直接讀寫記憶體,而不需要任何資料的拷貝。比如像管道和消息隊列,需要在核心和使用者空間進行四次的資料拷貝。

1

2

3

4

5

<code>#</code><code>include</code> <code>&lt;sys/mman.h&gt;</code>

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

<code>int munmap(void *start, size_t length);</code>

第一個函數mmap,将檔案描述符fd中的内容放到記憶體start --- ( start+ length) 的空間中。

port: 期望的記憶體保護方式,比如記憶體可讀/可寫/可執行,但是不能與檔案的打開模式沖突。就是隻能是檔案權限的子集。

flag: 指定映射對象的類型

fd: 被映射的檔案描述符。

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

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

<a href="http://man7.org/linux/man-pages/man2/mmap.2.html">http://man7.org/linux/man-pages/man2/mmap.2.html</a>

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

6

7

8

9

10

11

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

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

<code>...</code>

<code>mmap2(NULL, 31457280, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, 1232, 0) = 0xb5ce7000</code>

<code>nanosleep({3600, 0},</code>

mmap2() 系統調用執行的操作幾乎與mmap(2) 一樣,唯一的差別在于最後一個參數給出的在檔案中的偏移是以4096-位元組為機關。

這個mmap就在記憶體中空出30M的空間做記憶體映射

php的apc大緻原理是将php的opcode(php的操作碼)使用mmap映射(就是複制)到共享記憶體中,然後下次使用者再通路調用php通路,就可以直接去共享記憶體中讀取,而不需要再到磁盤上讀取了。

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

本文轉自軒脈刃部落格園部落格,原文連結:http://www.cnblogs.com/yjf512/p/3171056.html,如需轉載請自行聯系原作者