救命,Linux正在吃掉我的內存!
內存發現自己的空閑空間越來越少,經過一番調查,發現罪魁禍首居然是Linux老大!
內存:Linux老大,這也沒幾個程序在運行,可是你為什么老是占用我的內存啊,內存都快被你吃光了!
Linux :你的容量那么大,空間閑著也是閑著,我啊,把那些空閑的空間都當成文件緩存了!

內存: 你看看你, 把這文件“拆成”了4K的碎片,這兒放一片,那兒放一片,把我的內存空間搞得亂糟糟的。
Linux :這叫做Page Cache , 其實一點也不亂,文件在哪一“片”內存中放著,我記得清清楚楚。我這么做也是不得已而為之啊,硬盤太慢,比你慢幾萬倍。CPU的一秒,你這里就是6分鐘,硬盤那里就是好幾個月!每次從他那里讀點兒數據,幾個月才給我回話, 我只好把讀出來的數據先緩存到你這里了。

內存看到這張表格,不由得咂舌:沒想到這外面的世界如此之慢啊!
正在此時, 一個叫helloworld的程序要讀取文件。
helloworld :老大,我給你發了一個read系統調用,要讀取config.txt的前1024個字節,把結果放到我的buffer中。
Linux :好,讓我看看config.txt是不是已經在Page Cache中了,真不巧,還沒緩存過。內存老弟,我又要吃你的空閑空間了。
Linux在內存中分配了一個4k 大小的page frame, 向硬盤發出DMA指令,讀取cong.txt的4k的數據。

內存感覺奇怪:人家helloworld只要1024個字節,你干嘛讓硬盤發過來4K數據?
Linux :我這里Page cache 都是以4K為單位的, 讀一次得等幾個月,還不多讀一點?再說helloworld這小子很可能繼續讀文件的后續部分,下次就不用訪問硬盤了。
過了“幾個月” , 硬盤的數據復制到了內存的Page cache 中

內存說:這就完事了吧?
Linux :怎么可能!我得從Page cache 中取出前1024個字節,復制到helloworld指定的buffer 中。
這個buffer其實是helloworld虛擬地址空間heap上的地址,物理地址也是在你的內存中。

內存:我的天!難道數據要在我內存中出現兩份?
Linux :沒錯!你不知道,復制數據還得用CPU呢!很費勁的。
helloworld:老大,能不能讓我直接訪問你Page cache 中的數據?
Linux :那怎么行,你在用戶空間,我在內核空間,你要是能訪問,在我這里搗亂怎么辦?必須禁止!
內存:嗯,有道理,不過,要是還有個程序,也要讀取config.txt的前1024個字節,怎么辦?
Linux: 那就簡單了啊, 我一查就知道數據已經在Page cache中了,不用等幾個月從硬盤讀了,直接復制到那個程序的緩沖區就行了。
內存:啊?這數據重復太多了吧!

Linux :嗯,確實是個問題,現在這些程序,動輒訪問幾十個文件,每個程序都復制一份,確實是巨大的浪費。
內存:我給你支個招,既然那些程序運行訪問的都是虛擬地址,你讓這些虛擬地址映射到Page cache上,大家不就可以共享了。
Linux :好主意,我來提供一個叫做mmap的系統調用,完成你說的功能。

helloworld運行結束,退出了。
內存: helloworld退出了,你一會兒會清理掉對應的page cache吧?
Linux:暫時不會!
內存:啊?怪不得內存快被你吃光了!
Linux : 唉呀,你的內存閑著也是閑著,文件緩存著,下次再訪問的時候,性能會有巨大提升!你放心,我會在合適的時機清理掉page cache的。
內存:那如果helloword修改文件內容呢?會立即寫入硬盤嗎?
Linux :也不會,我只是標記這個Page cache “dirty”了, 然后我定期寫入硬盤。
內存:你怎么能這樣!這不是欺騙那些程序嗎!那要是斷電怎么辦?
Linux:對于需要及時寫入硬盤的,有兩種辦法,一是調用我提供的fsync方法強制寫入硬盤,二是在訪問文件的時候,可以指定不用Page cache。
內存:相當于什么都沒說,不用Page cache 多慢啊。
Linux :你現在也知道page cache的重要性了吧。page cache 是一種比較通用的文件緩存機制,是我來管理的。有些應用,比如數據庫,他需要更加靈活、更加復雜的文件緩存,那他就不用page cache ,自己另起爐灶了。
內存:啊?數據庫也在把我當作緩存?
Linux : 哈哈,是啊,要怪就怪硬盤吧,誰讓它那么慢!不過他要是和你一樣快,你小子就要下崗了,你想想,在一個訪問速度超快,容量超大,還不怕斷電威脅的存儲器面前,你是不是就變成渣渣了?
內存嘆了一口氣: 好吧,我也管不了了,你們隨意折騰吧。
后記:本文的第一個圖和標題來自
https://www.linuxatemyram.com/, 文章的內容參考了https://manybutfinite.com/post/page-cache-the-affair-between-memory-and-files/ ,確切說,本文是加了料的改編版, 這個博客還有幾篇關于虛擬內存的文章,非常棒,強烈建議大家去看看英文原文。
如需轉載,請通過作者微信公眾號coderising獲取授權