文章是抄的,https://www.jianshu.com/p/7044e0b9ab7a?from=singlemessage
pagecache
linux對文件的讀寫必須先走pagecache,pagecache是內存中的一塊區域,這樣做的好處是,在寫入的時候不直接寫入硬盤,而是寫入內存,可以加速讀寫。后續操作系統會自動把其內容刷到硬盤上。
例如我們調用操作系統的write函數,直接寫入到pagecache中而不是磁盤中。后續會將數據拷貝到內核態,再拷貝到硬盤上,這個過程操作系統可以為我們完成,當然我們我們也可以手動執行刷盤。
mmap
這里就要介紹一下mmap的優點了,mmap和write/read一樣需要從pagecache中進行刷盤,但是mmap的好處就是減少了一次數據復制,直接將pagecache刷到硬盤上而不需要經過內核態。
最后再說一下page cache的話題,從上面所說我們從磁盤文件中讀取的內容都會存在page cache中,但當我們關閉這個文件時,page cache中內容會立馬釋放掉嗎?答案是否,磁盤的讀取速度比內存慢太多,如果能命中page cache可以顯著提升性能,萬一后續又有對這個文件的操作,系統就可以很快速的響應。當然,這些文件內容也不是一直存在page cache中的,一般只要系統有空閑物理內存,操作系統都會拿來當緩存使用,但當物理內存不夠用,內存會清理出部分page cache應急。
還有就是普通的write調用只是將數據寫到page cache中,並將其標記為dirty就返回了,磁盤I/O通常不會立即執行,這樣做的好處是減少磁盤的回寫次數,提供吞吐率,不足就是機器一旦意外掛掉,page cache中的數據就會丟失。一般安全性比較高的程序會在每次write之后,調用fsync立即將page cache中的內容回寫到磁盤中。
DirectIo
哈哈,看到了這里,沒想到還有一種刷盤方式吧?對,就是dio。從上面我們可以看出來,操作系統為了保持自身的穩定、安全性,使用了頁式管理或者內核態拷貝。這里我們單看mmap所帶來的問題。可以說mmap是一種比較快的落盤方式了。但是由於linux本身用的還是頁式管理(mmap一樣),它不可避免的會導致缺頁中斷的現象,這時候會進行頁面置換算法,想想還是有點耗時的。
對此,linux本身提供了dio的接口,使得數據直接從應用程序地址空間落到硬盤上。當然這里如果要加快讀寫,可以自己設定緩沖區,而不是用pagecache,例如數據庫管理系統的實現
我的理解是
MappedByteBuffer buffer = fc.map(MapMode.READ_WRITE, 0, 1000); for (int i = 0;i< 100000;i++){ buffer.put((byte)65); }
fc是FileChannel
