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

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. postgres服务安装,启动和配置

    安装以及启动 yum install readline-devel tar xf postgresql-11.1.tar.gz cd postgresql-11.1 ./configure --pre ...

  2. layout -panel01

    <script src="~/jquery-easyui-1.5.5.2/jquery.min.js"></script> <link href=&q ...

  3. sed编辑器基础

    一. 更多的替换选项 ①替换标记 root@localhost sed]# cat data4.txt This is a test of the test script. This is the s ...

  4. redis集群-4

    redis集群原理 redis cluster在设计的时候,就考虑到了去中心化,去中间件,也就是说,集群中的每个节点都是平等的关系,都是对等的,每个节点都保存各自的数据和整个集群的状态.每个节点都和其 ...

  5. 51nod1340地铁环线

    经典题. 经典差分约束模型. 但是 显然这个总长是有上下界的. 直接二分总长,判断有没有负环 如果没有负环好办,有负环就不知道怎么偏了. 因为没有单调性! (如果所有没有单调性的函数图像,都知道往哪里 ...

  6. [CSP-S模拟测试47]反思+题解

    打开题面,T3似乎被换过了.(那我就更有理由直接弃掉了) T1是我最害怕的乱搞题,赶紧扔了看T2.发现是个sb板子?雨天的尾巴弱化版? 然而线段树合并早忘干净了(最近几道可以线段树合并的题都是用别的方 ...

  7. SPOJ_QTREE系列题解

    QTREE4 #pragma comment(linker, "/STACK:102400000,102400000") //#include<bits/stdc++.h&g ...

  8. JS 常用字符串,数组操作

    JavaScript String/Array对象 JS String对象   String 对象属性 属性 描述 constructor 对创建该对象的函数的引用 length 字符串的长度 pro ...

  9. MySQL高级学习笔记(七):MySql主从复制

    文章目录 复制的基本原理 slave会从master读取binlog来进行数据同步 三步骤+原理图 复制的基本原则 复制的最大问题 一主一从常见配置 mysql版本一致且后台以服务运行(双方能够pin ...

  10. thymeleaf数组下标

    <tr th:if="${exercisers != null}"th:each="exerciser:${exercisers}"> <td ...