`
vvggsky
  • 浏览: 66909 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

MappedByteBuffer内存映射

    博客分类:
  • J2SE
阅读更多
通过把一个套接字通道(SocketChannel)注册到一个选择器(Selector)中,不时调用后者的选择(select)方法就能返回满足的选择键(SelectionKey),键中包含了SOCKET事件信息.
异步套接字对服务器程序来说更具吸引力.一般同步SOCKET服务器的实现都是采用线程池来处理客户请求的,基于请求超时时间和并发线程数目的限制,如果并发处理能力能够达到上千就已经是不错了.异步服务器的能力则至少是它的数倍(有人测试一个简单的ECHO服务程序,说可以达到上万个并发,不知道是否真的能达到).

SocketChannel的读写是通过一个类叫ByteBuffer(java.nio.ByteBuffer)来操作的.这个类本身的设计是不错的,比直接操作byte[]方便多了.
ByteBuffer有两种模式:直接/间接.间接模式最典型(也只有这么一种)的就是HeapByteBuffer,即操作堆内存(byte[]).但是内存毕竟有限,如果我要发送一个1G的文件怎么办?不可能真的去分配1G的内存.这时就必须使用"直接"模式,即MappedByteBuffer,文件映射.
先中断一下,谈谈操作系统的内存管理.一般操作系统的内存分两部分:物理内存;虚拟内存.虚拟内存一般使用的是页面映像文件,即硬盘中的某个(某些)特殊的文件.操作系统负责页面文件内容的读写,这个过程叫"页面中断/切换".
MappedByteBuffer也是类似的,你可以把整个文件(不管文件有多大)看成是一个ByteBuffer.这是一个很好的设计,除了一点,令人头疼的一点.

MappedByteBuffer只能通过调用FileChannel的map()取得,再没有其他方式.但是令人奇怪的是,SUN提供了map()却没有提供unmap().这样会导致什么后果呢?
举个例子,文件test.tmp是一个临时构建的文件,在业务处理(通过SocketChannel发送)完之后将不再有效.一般的做法都是这样的:
(1)File file = new File("test.tmp");
FileInputStream in = new FileInputStream(file);
FileChannel ch = in.getChannel();
MappedByteBuffer buf = ch.map(FileChannel.MapMode.READ_ONLY, 0, file.length());
(2)SocketChannel sch = 已经构造好了;
while (buf.hasRemaining())
    sch.write(buf);
(3)ch.close();
in.close();
file.delete();


上面的操作都会正常的完成,除了最后一步:文件无法删除!即使你通过资源管理器直接强制删除也不行,说"文件正在使用".
为什么会出现这种情况?
说"文件正在使用",说明文件句柄没有清零,还有在使用它的地方---就是被MappedByteBuffer占用了!尽管FileChannel,FileInputStream都已经关闭了,但是在map里还打开着一个文件句柄.但是在外部看不见也无法操作它.那么这个句柄在什么时候才会正常地关闭呢?根据JAVADOC的说明,是在垃圾收集的时候.而众所周知垃圾收集是程序根本无法控制的.
分享到:
评论

相关推荐

    Java NIO 应用使用内存映射文件实现进程间通信

    在Java NIO中,内存映射文件(MappedByteBuffer)是一个重要的特性,它允许将文件直接映射到内存中,以便于快速访问和修改文件内容。这一特性不仅提高了读写效率,而且还能用于进程间通信(IPC)。 内存映射文件的...

    【IT十八掌徐培成】Java基础第27天-01.MappedMemoryBuffer-文件内存映射缓冲区.zip

    在标题和描述中提到的“文件内存映射缓冲区”是Java处理大文件的一种高级技术,它允许将文件直接映射到虚拟内存中,从而使得程序可以直接对文件进行读写操作,而无需通过传统的I/O流。 MappedByteBuffer的使用涉及...

    j2se项目源码及介绍_last指令

    返回说明 @return MappedByteBuffer 内存映射缓冲。 异常说明 throws 考虑异常 流程原理 调用实例 函数原型 private void readLog(MappedByteBuffer buffer, Vector<LogRecord> logins,Vector<LogRecord> ...

    深入浅出MappedByteBuffer.pdf

    **MappedByteBuffer**是Java NIO中用于内存映射文件的工具,它允许将文件内容直接映射到Java虚拟机的内存中,从而提供高效的文件读写性能。相比于传统的IO操作,MappedByteBuffer避免了数据在用户空间和内核空间之间...

    java 深入理解内存映射文件原理

    在Java中,使用内存映射文件通常通过java.nio包中的MappedByteBuffer类实现。通过FileChannel的map()方法,可以将文件映射到内存,从而提高大文件处理的性能。例如,以下代码展示了如何使用内存映射文件读取10MB的...

    Java中用内存映射处理大文件的实现代码

    对比实验中,我们使用了FileInputStream、BufferedInputStream以及RandomAccessFile分别进行文件读取,可以看到,使用内存映射文件(MappedByteBuffer)的读取速度通常会显著快于传统的I/O流,特别是在处理大文件时...

    Java内存映射 大文件轻松处理

    Java中的内存映射文件操作主要依赖于`java.nio`包中的`MappedByteBuffer`类。`MappedByteBuffer`是一个特殊的`ByteBuffer`,它可以与文件内容直接关联,实现内存和文件的一对一映射。通过`FileChannel`的`map`方法,...

    Java中使用内存映射实现大文件上传实例

    最后,使用`FileChannel`和`MappedByteBuffer`实现内存映射,将整个文件映射到内存,这样文件操作就直接在内存中完成,无需经过操作系统内核。 内存映射的优势在于: 1. **减少I/O操作**:映射后的文件可以直接在...

    MemMapComm:代码存储库,用于使用Java的内存映射文件测试IPC

    在Java中,内存映射文件是通过`java.nio.MappedByteBuffer`类来实现的,它允许程序将文件的一部分或全部映射到虚拟内存空间,从而使得多个进程可以直接共享数据,而无需传统的读写文件操作。 **内存映射文件的工作...

    java读取大文件

    为了有效地读取大文件,可以使用缓冲区(Buffer)和内存映射文件(MappedByteBuffer)技术。下面将详细解释如何使用这些技术以及代码中的关键部分。 1. **缓冲区(Buffer)**: Java中的缓冲区是用于提高数据读写...

    commons-mmf.rar_java nio_java共享内存_共享内存

    在Java中,可以通过`java.nio.MappedByteBuffer`类来实现共享内存功能,这被称为内存映射文件(Memory-Mapped File,MMF)。 `MappedByteBuffer`是NIO中的一种特殊缓冲区,它将文件的一部分映射到内存中,使得文件...

    mmapcom:内存映射文件实用程序库,用于存放更大尺寸的文件

    而`mmapcom`库利用了Java的`java.nio.MappedByteBuffer`类,该类提供了内存映射文件的功能,可以将文件的一部分或全部映射到内存中,从而减少了磁盘I/O次数,提升了读写速度。 `mmapcom`库的使用步骤大致如下: 1....

    IPC.rar_IPC_java i_java ipc_java共享内存_共享内存

    1. **创建内存映射文件**:使用`java.nio.channels.FileChannel`的`map()`方法,将磁盘上的文件映射到内存中。这一步实际上是在操作系统层面创建了一个共享的内存区域。 2. **获取映射缓冲区**:通过调用`...

    java大文件读取-乔乐共享

    内存映射文件是一种特殊的文件处理方式,它能够将文件的一部分或者全部映射到内存地址空间中,从而允许程序像访问内存一样读写文件中的数据。这种方法特别适合处理大文件,因为它可以减少文件I/O操作,提高读写效率...

    文件高速传输读写 客户端服务端

    本主题聚焦于Java平台下如何实现高效的文件操作,特别是利用内存映射(MappedByteBuffer)进行读写和通过网络进行文件传输。以下是相关的知识点详解: 1. **内存映射文件(MappedByteBuffer)**: 内存映射文件是...

    J2SE.development.code.MemMapFile.rar_Java编程_Java_

    在Java中,我们可以通过`java.nio.MappedByteBuffer`类来实现内存映射文件。当我们创建一个MappedByteBuffer实例时,实际上是将文件的部分或全部内容映射到进程的虚拟地址空间中,这样就可以像操作普通数组一样操作...

    java csv大数据量导出(千万级别,不会内存溢出)

    此外,为了避免内存中的临时数据过多,还可以考虑使用Java的内存映射文件(Memory-Mapped File)。通过MappedByteBuffer,我们可以让操作系统负责数据的缓存和页面交换,这在处理大文件时能显著降低内存使用。 在...

    Mapped_Store

    《Mapped_Store:深入理解Java内存映射文件》 在Java编程中,`Mapped_Store` 提到了一个关键的概念,那就是内存映射文件(Memory-Mapped File)。这个技术是Java NIO(New IO)库的一部分,它允许我们将文件直接...

    Java解析SO(ELF)文件

    最后,需要注意的是,解析二进制文件需要对文件格式有深入理解,同时也需要处理好异常情况,例如文件格式不正确、内存映射失败等。对于Java开发者来说,这可能是一个挑战,但也是一次学习系统底层知识和提升编程技能...

    java读取超大文本文件

    对于需要随机访问或文件特别大的情况,推荐使用`RandomAccessFile`和`FileChannel`的组合,特别是利用`MappedByteBuffer`进行内存映射文件读取。这种方式能够显著提高文件的读取速度,因为数据直接从磁盘映射到内存...

Global site tag (gtag.js) - Google Analytics