java中的mmap实现--转
- 什么是mmap ??? mmap對于c程序員很熟悉,對于java程序員有點(diǎn)陌生。簡而言之,將文件直接映射到用戶態(tài)的內(nèi)存地址,這樣對文件的操作不再是write/read,而是直接對內(nèi)存地址的操作。?
?
- ??? 在c中提供了三個(gè)函數(shù)來實(shí)現(xiàn)?
?
- ??? [list]?
?
- ???
- mmap 進(jìn)行映射 ???
- munmap 取消映射 ???
- msync 進(jìn)程在映射空間的對共享內(nèi)容的改變并不直接寫回到磁盤文件中,往往在調(diào)用munmap()后才執(zhí)行該操作。?? ???
??? 具體參照http://blog.chinaunix.net/uid-24517893-id-164217.html
- java中的map
??? java中的FileChannel,提供了map和force方法,map創(chuàng)建文件和內(nèi)存的映射,?
??
??? 返回一個(gè)MappedByteBuffer,這是一個(gè)DirectBuffer,其中包含一個(gè)內(nèi)存地址,然后可用就做一些讀寫操作。?
??? 還有另外一個(gè)方法是force,是將內(nèi)存的更新的內(nèi)容刷到磁盤中。?
??? 在這里拋出一個(gè)問題,force是必須調(diào)用的,如果不調(diào)用force會怎樣。?
??? 我試著寫了一段小程序來試驗(yàn)?
???
??? 然后觀察文件發(fā)現(xiàn)文件中是有1000個(gè)B的,那么就是說不調(diào)用force,內(nèi)容也會落到磁盤中的。既然不用force內(nèi)容也可以落到磁盤中,那force的作用什么呢?帶著這個(gè)問題我查看了openJdk的force和map的實(shí)現(xiàn)和linux中mmap的實(shí)現(xiàn)。
- JDK的force和map的實(shí)現(xiàn)
? 通過FileChannel->FileChannelImpl的native知道,對linux平臺調(diào)用應(yīng)該在D:\git\openjdk\jdk\src\solaris\native\sun\nio\ch下的FileChannelImpl.c?
Java代碼???
Java代碼??
原來force是調(diào)用的fdatasync(fsync),這不是linux中buffered IO,write(2)以后需要調(diào)用的方法嗎,難道m(xù)map也是走的BufferdIO那一套,首先寫到page cache,然后由pdflush定時(shí)刷到磁盤中,那這么說mmap只是在進(jìn)程空間分配一個(gè)內(nèi)存地址,真實(shí)的內(nèi)存還是使用的pagecache。所以force是調(diào)用fsync將dirty page刷到磁盤中,但mmap還有共享之類的實(shí)現(xiàn)起來應(yīng)該很復(fù)雜。
- 驗(yàn)證
? 為了驗(yàn)證上面的假設(shè),我做了一個(gè)實(shí)驗(yàn)。在linux下起兩個(gè)終端,A終端通過上面的程序向a.txt寫入數(shù)據(jù),B終端使用tailf a.txt觀察數(shù)據(jù)的寫入。奇怪的是A終端執(zhí)行完,B終端立馬就成看到數(shù)據(jù),而不是等30s以后pdflush刷到磁盤以后才能看到,難道前面的假設(shè)錯(cuò)了?或者另一種可能tailf查看到也是在page cache中讀取的。那只需查看下文件的page是不是dirty就知道了。?
Java代碼??
就可以查看一個(gè)文件的page是否是dirty。?
重新實(shí)現(xiàn)使用如上腳本觀察?
果然是dirty的,然后繼續(xù)等待一段時(shí)間再次執(zhí)行發(fā)現(xiàn)已經(jīng)是clean,被刷到磁盤中。?
?
- 結(jié)論
1. mmap,底層還是走的BufferedIO,好處大概是減少了內(nèi)核態(tài)和用戶態(tài)的內(nèi)存拷貝,這點(diǎn)不太確定,對內(nèi)核不熟。?
2. force,參數(shù)為true調(diào)用fsync,false調(diào)用fdatasync,fdatasync只刷數(shù)據(jù)不刷meta數(shù)據(jù)?
3. 即使不調(diào)用force,內(nèi)核也會定期將dirty page刷到磁盤,默認(rèn)是30s。?
?
原文來自:http://xiaoz5919.iteye.com/blog/2093323
轉(zhuǎn)載于:https://www.cnblogs.com/davidwang456/p/3853977.html
總結(jié)
以上是生活随笔為你收集整理的java中的mmap实现--转的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java SE 6 新特性: 编译器 A
- 下一篇: 海量存储系列上--转载,值得一读