MappedByteBuffer
计算机内存管理
原文链接 https://www.cnblogs.com/guozp/p/10470431.html
MMC:CPU的内存管理单元。
物理内存:即内存条的内存空间。
虚拟内存:计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续的可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。
页面文件:操作系统反映构建并使用虚拟内存的硬盘空间大小而创建的文件,在windows下,即pagefile.sys文件,其存在意味着物理内存被占满后,将暂时不用的数据移动到硬盘上。
缺页中断:当程序试图访问已映射在虚拟地址空间中但未被加载至物理内存的一个分页时,由MMC发出的中断。如果操作系统判断此次访问是有效的,则尝试将相关的页从虚拟内存文件中载入物理内存。
MappedByteBuffer介绍
MappedByteBuffer 是Java NIO中引入的一种硬盘物理文件和内存映射方式,当物理文件较大时,采用MappedByteBuffer,读写性能较高,其内部的核心实现是DirectByteBuffer(JVM 堆外直接物理内存)。
JVM 进程通过内存映射方式加载的物理文件并不会耗费同等大小的物理内存。当应用程序访问数据时,程序通过虚拟地址寻址对应的内存页,如果物理内存中不存在对应页,MMU则会产生缺页中断异常,CPU尝试从系统Swap分区中查找,如仍不存在,则会直接从硬盘中物理文件中读取。
传统的基于文件流的方式读取文件方式是系统指令调用,文件数据首先会被读取到进程的内核空间的缓冲区,而后复制到进程的用户空间,这个过程中存在两次数据拷贝;而内存映射方式读取文件的方式,也是系统指令调用,在产生缺页中断后,CPU直接从磁盘文件load数据到进程的用户空间,只有一次数据拷贝。
FileChannel提供了map方法把磁盘文件映射到虚拟内存,通常情况可以映射整个文件,如果文件比较大,可以进行分段映射。
内存映像文件访问的方式,共三种:
a) MapMode.READ_ONLY:只读,试图修改得到的缓冲区将导致抛出异常。
b) MapMode.READ_WRITE:读/写,对得到的缓冲区的更改最终将写入文件;但该更改对映射到同一文件的其他程序不一定是可见的。
c) MapMode.PRIVATE:私用,可读可写,但是修改的内容不会写入文件,只是buffer自身的改变。
MappedByteBuffer在处理大文件时的确性能很高,但也存在一些问题,其所对应的内存使用的是JVM堆外内存,JVM young gc和CMS gc并不能触发回收MappedByteBuffer对应的内存,只有full gc(stop the world的方式)可以使其回收内存,堆外直接内存会根据自己的情况(当需要新分配直接内存时,如果所剩堆外内存空间不够,第一次产生OutOfMemoryError时)来触发 System.gc(),此处有坑,若JVM配置了参数-XX:DisableExplicitGC,System.gc()将不会触发full gc,最终导致内存泄漏。而且触发其内存回收的时间点是不确定的。Java api文档中标注:
A mapped byte buffer and the file mapping that it represents remain valid until the buffer itself is garbage-collected.
在应用程序频繁使用堆外内存时,还可以通过-XX:MaxDirectMemorySize来指定最大的堆外内存大小,当使用达到了阈值的时候将调用System.gc来做一次full gc,以此来回收掉游离状态的堆外内存。
因此,在使用堆外内存高性能的福利的同时,及时的回收掉废弃掉的内存是十分关键的。
性能分析
从代码层面上看,从硬盘上将文件读入内存,都要经过文件系统进行数据拷贝,并且数据拷贝操作是由文件系统和硬件驱动实现的,理论上来说,拷贝数据的效率是一样的。
但是通过内存映射的方法访问硬盘上的文件,效率要比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 remain* valid until the buffer itself is garbage-collected.
原文链接 https://www.cnblogs.com/guozp/p/10470431.html
MappedByteBuffer的更多相关文章
- Java--Stream,NIO ByteBuffer,NIO MappedByteBuffer性能对比
目前Java中最IO有多种文件读取的方法,本文章对比Stream,NIO ByteBuffer,NIO MappedByteBuffer的性能,让我们知道到底怎么能写出性能高的文件读取代码. pack ...
- Atitit.病毒木马的快速扩散机制原理nio 内存映射MappedByteBuffer
Atitit.病毒木马的快速扩散机制原理nio 内存映射MappedByteBuffer 1. Java NIO(New Input/Output)1 1.1. 变更通知(因为每个事件都需要一个监听者 ...
- Java NIO教程 MappedByteBuffer
之前跟大家说过,要讲MappedByteBuffer,现在我来履行承诺了. 首先从大体上讲一下MappedByteBuffer究竟是什么.从继承结构上来讲,MappedByteBuffer继承自Byt ...
- MappedByteBuffer读写文件
一. MappedByteBuffer java把文件映射到内存中,避免堆内存产生大对象引起full gc.mappedByteBuffer的读写速度都要超过堆内读写文件的速度 public clas ...
- RandomAcessFile、MappedByteBuffer和缓冲读/写文件
项目需要进行大文件的读写,调查测试的结果使我决定使用MappedByteBuffer及相关类进行文件的操作,效果不是一般的高. 网上参考资源很多,如下两篇非常不错: 1.花1K内存实现高效I/O的Ra ...
- MappedByteBuffer高速缓存文件、RandomAccessFile随机访问
说到高速缓存存储,处理读写文件,那就不得不说MappedByteBuffer. 看了好多文章以后写一下自己的总结. 在这里先介绍一下相关的类与方法. 先说一下Buffer.ByteBuffer.Map ...
- Java NIO之内存映射文件——MappedByteBuffer
大多数操作系统都可以利用虚拟内存实现将一个文件或者文件的一部分"映射"到内存中.然后,这个文件就可以当作是内存数组来访问,这比传统的文件要快得多. 内存映射文件的一个关键优势是操作 ...
- Kafka-4614问题复盘 (MappedByteBuffer未关闭导致慢磁盘访问)
很早之前就想动笔就这个kafka bug总结一番了,只是这个问题既不是本人发现,也不是自己动手修复,终归是底气不足,故而一直耽搁下来.怎奈此问题实在是含金量十足,又恰逢最近有人询问Kafka 0.10 ...
- Java RandomAccessFile与MappedByteBuffer
Java RandomAccessFile与MappedByteBuffer https://www.cnblogs.com/guazi/p/6838915.html
随机推荐
- 玩转spring MVC(七)----拦截器
继续在前边的基础上来学习spring MVC中拦截器的使用,下面通过一个例子来实现(完整项目在这里下载:http://download.csdn.net/detail/u012116457/84334 ...
- Golang 嵌套map赋值办法
http://my.oschina.net/sol/blog/159060 m := map[string]map[string]string{} mm, ok := m["kkk" ...
- Goroutine陷阱
Go在语言层面通过Goroutine与channel来支持并发编程,使并发编程看似变得异常简单,但通过最近一段时间的编码,越来越觉得简单的东西,很容易会被滥用.Java的标准库也让多线程编程变得简单, ...
- BZOJ_4476_[Jsoi2015]送礼物_01分数规划+单调队列
BZOJ_4476_[Jsoi2015]送礼物_01分数规划+单调队列 Description JYY和CX的结婚纪念日即将到来,JYY来到萌萌开的礼品店选购纪念礼物. 萌萌的礼品店很神奇,所有出售的 ...
- BZOJ_4726_[POI2017]Sabota?_树形DP
BZOJ_4726_[POI2017]Sabota?_树形DP Description 某个公司有n个人, 上下级关系构成了一个有根树.其中有个人是叛徒(这个人不知道是谁).对于一个人, 如果他 下属 ...
- Cocos.js
l SDK下载:http://cn.cocos2d-x.org/download/ l js类库:http://www.cocos2d-x.org/filecenter/jsbuilder/
- bootstrap小知识
栅格系统 1. row必须放到container和container-fluid里面 2. 你的内容应当放置于"列(column)"内,并且,只有"列(column)&q ...
- 【Teradata SQL】从中文数字字母混合字符串中只提取数字regexp_substr
目标:从中文数字字母的字符串中只提取数字 sel regexp_substr('mint choc中文11国1','\d+')
- MIP技术交流分享(3月9日)
3月9日上周四下午,MIP 团队工程师与去哪儿酒店云.众荟的 Web 前端工程师进行了一次面对面的技术交流. 在这次交流中,MIP 工程师主要分享了 MIP 技术原理,MIP 加速原理,以及 MIP ...
- 关于JVM的垃圾回收(GC) 这可能是你想了解的
目录 1 JVM中Java对象的分类 2 JVM的GC类型及触发条件 2.1 Young GC 2.2 Full GC 3 Java对象生成时的内存申请过程 3 Oracle JDK中的垃圾收集器 3 ...