标签:des blog http java 使用 strong
具体参照http://blog.chinaunix.net/uid-24517893-id-164217.html
java中的FileChannel,提供了map和force方法,map创建文件和内存的映射,
返回一个MappedByteBuffer,这是一个DirectBuffer,其中包含一个内存地址,然后可用就做一些读写操作。
还有另外一个方法是force,是将内存的更新的内容刷到磁盘中。
在这里抛出一个问题,force是必须调用的,如果不调用force会怎样。
我试着写了一段小程序来试验
然后观察文件发现文件中是有1000个B的,那么就是说不调用force,内容也会落到磁盘中的。既然不用force内容也可以落到磁盘中,那force的作用什么呢?带着这个问题我查看了openJdk的force和map的实现和linux中mmap的实现。
通过FileChannel->FileChannelImpl的native知道,对linux平台调用应该在D:\git\openjdk\jdk\src\solaris\native\sun\nio\ch下的FileChannelImpl.c
原来force是调用的fdatasync(fsync),这不是linux中buffered IO,write(2)以后需要调用的方法吗,难道mmap也是走的BufferdIO那一套,首先写到page cache,然后由pdflush定时刷到磁盘中,那这么说mmap只是在进程空间分配一个内存地址,真实的内存还是使用的pagecache。所以force是调用fsync将dirty page刷到磁盘中,但mmap还有共享之类的实现起来应该很复杂。
为了验证上面的假设,我做了一个实验。在linux下起两个终端,A终端通过上面的程序向a.txt写入数据,B终端使用tailf a.txt观察数据的写入。奇怪的是A终端执行完,B终端立马就成看到数据,而不是等30s以后pdflush刷到磁盘以后才能看到,难道前面的假设错了?或者另一种可能tailf查看到也是在page cache中读取的。那只需查看下文件的page是不是dirty就知道了。
就可以查看一个文件的page是否是dirty。
重新实现使用如上脚本观察
果然是dirty的,然后继续等待一段时间再次执行发现已经是clean,被刷到磁盘中。
1. mmap,底层还是走的BufferedIO,好处大概是减少了内核态和用户态的内存拷贝,这点不太确定,对内核不熟。
2. force,参数为true调用fsync,false调用fdatasync,fdatasync只刷数据不刷meta数据
3. 即使不调用force,内核也会定期将dirty page刷到磁盘,默认是30s。
原文来自:http://xiaoz5919.iteye.com/blog/2093323
java中的mmap实现--转,布布扣,bubuko.com
标签:des blog http java 使用 strong
原文地址:http://www.cnblogs.com/davidwang456/p/3853977.html