操作系统会在负责执行映射,用于操作大文件

java io操作中通常采用BufferedReader,BufferedInputStream等带缓冲的IO类处理大文件;java nio中引入了一种基于MappedByteBuffer操作大文件的方式,其读写性能极高

FileChannel提供了map方法把文件映射到虚拟内存,通常情况可以映射整个文件,如果文件比较大,可以进行分段映射

MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE, 0, 1024);   //fc-->FileChannel
//map通过native函数map0完成文件的映射工作,返回DirectByteBuffer

  

MappedByteBuffer的get方法最终通过DirectByteBuffer.get方法实现的

public byte get() {
return ((unsafe.getByte(ix(nextGetIndex()))));
}
public byte get(int i) {
return ((unsafe.getByte(ix(checkIndex(i)))));
}
private long ix(int i) {
return address + (i << 0);
}

  

map0()函数返回一个地址address,这样就无需调用read或write方法对文件进行读写,通过address就能够操作文件。底层采用unsafe.getByte方法,通过(address + 偏移量)获取指定内存的数据。

  1. 第一次访问address所指向的内存区域,导致缺页中断,中断响应函数会在交换区中查找相对应的页面,如果找不到(也就是该文件从来没有被读入内存的情况),则从硬盘上将文件指定页读取到物理内存中(非jvm堆内存)。
  2. 如果在拷贝数据时,发现物理内存不够用,则会通过虚拟内存机制(swap)将暂时不用的物理页面交换到硬盘的虚拟内存中

性能:

从代码层面上看,从硬盘上将文件读入内存,都要经过文件系统进行数据拷贝,并且数据拷贝操作是由文件系统和硬件驱动实现的,理论上来说,拷贝数据的效率是一样的。
但是通过内存映射的方法访问硬盘上的文件,效率要比read和write系统调用高,这是为什么?

  • read()是系统调用,首先将文件从硬盘拷贝到内核空间的一个缓冲区,再将这些数据拷贝到用户空间,实际上进行了两次数据拷贝;
  • map()也是系统调用,但没有进行数据拷贝,当缺页中断发生时,直接将文件从硬盘拷贝到用户空间,只进行了一次数据拷贝。

所以,采用内存映射的读写效率要比传统的read/write性能高

总结:

    • MappedByteBuffer使用虚拟内存,因此分配(map)的内存大小不受JVM的-Xmx参数限制,但是也是有大小限制的。
    • 如果当文件超出1.5G限制时,可以通过position参数重新map文件后面的内容。
    • MappedByteBuffer在处理大文件时的确性能很高,但也存在一些问题,如内存占用、文件关闭不确定,被其打开的文件只有在垃圾回收的才会被关闭,而且这个时间点是不确定的。
      javadoc中也提到:A mapped byte buffer and the file mapping that it represents remainvalid until the buffer itself is garbage-collected.*

【NIO】MappedByteBuffer-内存映射文件 I/O的更多相关文章

  1. Java NIO之内存映射文件——MappedByteBuffer

    大多数操作系统都可以利用虚拟内存实现将一个文件或者文件的一部分"映射"到内存中.然后,这个文件就可以当作是内存数组来访问,这比传统的文件要快得多. 内存映射文件的一个关键优势是操作 ...

  2. JAVA NIO FileChannel 内存映射文件

      文件通道总是阻塞式的. 文件通道不能创建,只能通过(RandomAccessFile.FileInputStream.FileOutputStream)getChannel()获得,具有与File ...

  3. 【JavaNIO的深入研究4】内存映射文件I/O,大文件读写操作,Java nio之MappedByteBuffer,高效文件/内存映射

    内存映射文件能让你创建和修改那些因为太大而无法放入内存的文件.有了内存映射文件,你就可以认为文件已经全部读进了内存,然后把它当成一个非常大的数组来访问.这种解决办法能大大简化修改文件的代码.fileC ...

  4. Java NIO 内存映射文件

    Java NIO 内存映射文件 @author ixenos 文件操作的四大方法 前提:内存的访问速度比磁盘高几个数量级,但是基本的IO操作是直接调用native方法获得驱动和磁盘交互的,IO速度限制 ...

  5. NIO之通道(Channel)的原理与获取以及数据传输与内存映射文件

    通道(Channel) 由java.nio.channels包定义的,Channel表示IO源与目标打开的连接,Channel类似于传统的“流”,只不过Channel本身不能直接访问数据,Channe ...

  6. JAVA NIO之浅谈内存映射文件原理与DirectMemory

    JAVA类库中的NIO包相对于IO 包来说有一个新功能是内存映射文件,日常编程中并不是经常用到,但是在处理大文件时是比较理想的提高效率的手段.本文我主要想结合操作系统中(OS)相关方面的知识介绍一下原 ...

  7. 【NIO】NIO之浅谈内存映射文件原理与DirectMemory

    Java类库中的NIO包相对于IO 包来说有一个新功能是内存映射文件,日常编程中并不是经常用到,但是在处理大文件时是比较理想的提高效率的手段.本文我主要想结合操作系统中(OS)相关方面的知识介绍一下原 ...

  8. (转)NIO 内存映射文件

    内存映射文件 I/O 是一种读和写文件数据的方法,它可以比常规的基于流或者基于通道的 I/O 快得多. 内存映射文件 I/O 是通过使文件中的数据神奇般地出现为内存数组的内容来完成的.这其初听起来似乎 ...

  9. 内存映射文件MappedByteBuffer和Buffer的Scattering与Gathering

    上一篇讲到的DirectByteBuffer继承自MappedByteBuffer 一.MappedByteBuffer MappedByteBuffer的定义: A direct byte buff ...

  10. Java-NIO(五):通道(Channel)的数据传输与内存映射文件

    通道(Channel)的数据传输(采用非直接缓冲区) @Test public void testChannel() throws IOException { FileInputStream file ...

随机推荐

  1. php图片无损压缩的问题解决

    代码如下 <?php namespace App\Contract; use Carbon\Carbon; /** * 图片压缩封装类 * @author jackie <2019.11. ...

  2. 【leetcode】909. Snakes and Ladders

    题目如下: 解题思路:天坑题,不在于题目多难,而是要理解题意.题目中有两点要特别注意,一是“You choose a destination square S with number x+1, x+2 ...

  3. Yii2邮件发送

    1.在配置文件main-local.php components=>[]里面配置 'mailer' => [ 'class' => 'yii\swiftmailer\Mailer', ...

  4. STM32点LED灯

    一.建立项目模板 这里的user中重复引用了system_stm32f10x.c Output中选择Create HEXFile,并且可以选择输出路径. Listing中可以选择输出路径. 然后在C/ ...

  5. delphi 运行时提升软件到管理员权限

    //以管理员身份运行procedure RunAsAdmin(hWnd: HWND; aFile: string; aParameters: string);varsei: TShellExecute ...

  6. 2019 牛客暑期多校 第一场 H XOR (线性基)

    题目:https://ac.nowcoder.com/acm/contest/881/H 题意:求一个集合内所有子集异或和为0的长度之和 思路:首先集合内异或和,这是线性基的一个明显标志,然后我们不管 ...

  7. Python之-爬虫

    1.得到页面的HTML代码 第一个参数是URL 第二三个参数可以不传送,数据和时间 2.request请求 HTTP是基于请求和应答的,客户端发出请求,服务端做出响应,所以urllib2创建一个req ...

  8. HTML中多媒体标签技术说明

    在纯文本的HTML页面中加入图片,给原来单调乏味的页面添加生气.HTML语言中利用<IMG>标记插入图片. 1.图片标记<IMG>及其属性 在网站上,网页设计者都使用了大量精心 ...

  9. js 对象浅拷贝和深拷贝

    var model={name:"boy",age:13}; var CopyModel=model; console.log(CopyModel.name); model.nam ...

  10. jquery给表格绑值

    jquery给表格绑值 直接上代码了 <!DOCTYPE html> <html> <head> <meta charset="UTF-8" ...