【NIO】MappedByteBuffer-内存映射文件 I/O_track sun的博客-程序员宝宝

技术标签: java  操作系统  

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

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.*

转载于:https://www.cnblogs.com/itplay/p/11078559.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_30540691/article/details/97334160

智能推荐

10个运维人员需要知道的”系统进程”_study-linux的博客-程序员宝宝

在日常的运维工作中,当我们习惯性的执行ps命令后会看到很多“奇奇怪怪”的进程,而这些进程大部门都是系统的内核进程。很多同学对之了解的甚少,因此今天就为大家整理一篇入门级的系统进程介绍帖,希望能够帮助大家对操作系统进程的理解。在日常的运维工作中,当我们习惯性的执行ps命令后会看到很多“奇奇怪怪”的进程,而这些进程大部门都是系统的内核进程。很多同学对之了解的甚少,因此今天就为大家整

【BZOJ1951】[中国剩余定理][SDOI2010]古代猪文_二分抄代码的博客-程序员宝宝

求g的p次方%mod,根据费马小定理,g^sigma(C(n,d))(d|n)%mod=g^(sigma(C(n,d))(d|n)%(mod-1))%mod,然而mod-1不是质数,只能用把它拆成4个质因数,然后对4个模方程分别求解,先用lucas定理和费马小定里求出对4个质数取模的sigma的值(num[i]),注意,枚举因数d的时候枚举到sqrt(n)就可以了,同时加上C(N,I)和C(n,

chrome好用的几个插件-属于程序员的福利_做一个温柔的程序媛的博客-程序员宝宝

查看链接:http://www.jianshu.com/p/40d147ec84db?ref=myread目前我正在使用的几个插件:1、广告终结者2、ABP(也是屏蔽广告的一个插件)        3、lastPass:(这个插件是通过登录然后使用的,可以将自己的网站表单信息带入自己正在使用的电脑,非常好用)其它几个插件正在尝试。。敬请期

记一下chrome浏览器被毒霸域名劫持解决方案_归落的博客-程序员宝宝

记一下chrome浏览器被毒霸域名劫持解决方案卸载金山毒霸后,浏览器打开会跳转到毒霸页面卸载金山毒霸后,浏览器打开会跳转到毒霸页面把金山毒霸卸载之后,意外的发现自己的chrome浏览器打开的时候,跳出来的是毒霸的页面,被劫持了。按照网上在输入栏输入chrome://version/,发现命令行被重定向到毒霸页面。本来用安全卫士锁住主页,还是存在(看来腾讯还不够流氓,竟然被毒霸给上了)。按照网...

POJ1191-裸动态规划_ACM_Victoria的博客-程序员宝宝

#include #include #include using namespace std;const double INF=1000000000000.0;int n;double _x,w;double s[9][9];double f[9][9][9][9][16];int main(){ scanf("%d",&n); for (int i=0;

istio(v1.0.1)安装_jinyidong的博客-程序员宝宝

1、准备工作yelm安装2、istio安装istio安装文件下载curl -L https://git.io/getLatestIstio | sh -将istioctl加入环境变量cd istio-1.0.1export PATH=$PWD/bin:$PATHinstall custom resources definitionskubectl apply -f...

随便推点

NOIP2002-普及组复赛-第二题-级数求和_weixin_30345577的博客-程序员宝宝

题目描述Description  已知:Sn= 1+1/2+1/3+…+1/n。显然对于任意一个整数K,当n足够大的时候,Sn大于K。  现给出一个整数K(1&lt;=k&lt;=15),要求计算出一个最小的n;使得Sn>K。输入输出格式Input/output输入格式:一个正整数K。输出格式:一个正整数N。...

python练习12_い木乄子゛的博客-程序员宝宝

题目:判断101-200之间有多少个素数,并输出所有素数。 #!/usr/bin/python# -*- coding: UTF-8 -*-#from math import sqrtprime = []flag = Truefor i in range(101, 201): k = int(sqrt(i)) for j in range(2, k + 1): ...

python—异常处理_didaojiao4342的博客-程序员宝宝

Python 之-异常处理异常和错误part1:程序中难免出现错误,而错误分成两种1语法错误(这种错误,根本过不了Python解释器的语法检测,必须在程序执行前就改正)#语法错误示范一、if#语法错误示范二、def test: pass#语法错误示范三、print(haha2逻辑错误(逻辑错误)#用户输入...

spring boot 自动配置_中国lanwp的博客-程序员宝宝

文章目录springboot自动化配置spring boot mybatis plus依赖spring boot自动配置相关文件启动的自动配置类MybatisPlusAutoConfigurationspringboot自动化配置这里拿mybatis-plus-boot-starter 为例子说明,其他类似spring boot mybatis plus依赖spring boot引入依赖 - 包含了mybatis和mybatis-spring 及 mybatis-plus3.3.2版本

C++中pair使用详细说明_想去的远方的博客-程序员宝宝_c++ pair

一、pair的介绍pair是一个很实用的 "小玩意",当想要将两个元素绑在一起作为一个合成元素、又不想要因此定义结构体时,使用 pair 可以很方便地作为一个代替品。也就是说,pair 实际上可以看作一个内部有两个元素的结构体,且这两个元素的类型是可以指定的,如下:struct pair{ typeName1 first; typeName2 second;};二、pair的定义要使用 pair,应先添加头文件 #include &lt;utility&gt;...

autosar can协议栈 源码解读_AUTOSAR架构的CAN通讯_他在水中央的博客-程序员宝宝

宏观地介绍可参见:autosar.org/fileadmin/A2. AUTOSAR软件分层架构AUTOSAR架构在三个软件层之间划分出最高的抽象层:应用层(Application Layer, ASW),运行时环境(Runtime Environment, RTE)和底层软件(Basic Software, BSW),三者均在微控制器上运行。这里我们主要关注的是底层软件,它进一步分层为:服务层,...

推荐文章

热门文章

相关标签