`

【Java核心-基础】DirectBuffer 和 MappedByteBuffer

    博客分类:
  • Java
 
阅读更多

简述

Java NIO 中提供了 DirectBuffer、MappedByteBuffer 以提高IO效率。



 

DirectBuffer

DirectBuffer 占用的是 堆外内存。JVM 会在 DirectBuffer 上直接使用 “本地IO操作”(Native I/O Operations)。
Buffer 的地址对“本地IO操作”非常关键。所以在操作 堆内Buffer 时,JVM需要将其数据先复制到一个堆外Buffer,让“本地IO操作”读写此堆外Buffer。
这样可以防止GC活动改变堆内Buffer地址的影响(寻址更简单)。
所以使用DirectBuffer可以避免额外的数据复制,提高IO效率。同时也可以降低GC的工作量

当需要 容量较大长期使用 的缓存时可考虑使用 DirectBuffer。当然也需要测试确定是否能获得性能提升。
 

ByteBuffer buffer =  ByteBuffer.allocateDirect(1024);
public abstract class ByteBuffer {
  public static ByteBuffer allocateDirect(int capacity) {
    return new DirectByteBuffer(capacity);
  }

  public static ByteBuffer allocate(int capacity) {
    if (capacity<0)
      throw createCapacityException(capacity);
    return new HeapByteBuffer(capacity, capacity);
  }
  ...
}

 

MappedByteBuffer

MappedByteBuffer 可以 将文件内容映射到内存,供应用程序直接使用,省去数据在 内核空间 和 用户空间 之间传输的损耗。
它本质上也是一种 DirectBuffer。JDK 中用的是它的子类 DirectByteBuffer,这个类就实现了 DirectBuffer 接口。

MappedByteBuffer buffer = fileChannel.map(MapMode.READ_ONLY, 0, 1024);

 

内存管理

设置最大允许内存

对于这些占用堆外内存的对象,可以通过启动参数来设置最大占用空间。

-XX:MaxDirectMemory=512M

 

内存回收

DirectBuffer 一般是在 Full GC 时被回收。 可以显式调用 System.gc() 强制触发GC。
也可以像Netty那样 hack 到内部 主动调用释放方法;禁用显式调用 gc(-XX:+DisableExplicitGC)


DirectByteBuffer 的内部类 Deallocator 实现了具体的回收方法。由 Cleaner 调用该方法。

private static class Deallocator implements Runnable{
  ...
  public void run() {
    if (address == 0) {
      return;
    }
    UNSAFE.freeMemory(address);
    address = 0;
    Bits.unreserveMemory(size, capacity);
  }
}

 

诊断 和 跟踪 内存占用

可通过 JConsole 等一些图形化工具查看这些堆外内存。
也可以通过 jcmd 命令行查看:

  • 通过启动参数开启 Native Memory Tracking (NMT) 特性。(这会导致可观的性能下降)
  • 通过 jcmd 查看相关信息。

    如: jcmd <pid> VM.native_memory detail
    jcmd <pid> VM.native_memory baseline
    jcmd <pid> VM.native_memory detail.diff

 

  • 大小: 9.1 KB
分享到:
评论

相关推荐

    JAVA IO-NIO 详解

    - **Direct vs Non-Direct Buffer**: Direct Buffer直接映射到物理内存,Non-Direct Buffer在JVM堆上分配内存。 **3. Buffer的日常操作** - **put**: 向Buffer写入数据。 - **get**: 从Buffer读取数据。 - **flip*...

    java-instantcode-developing.rar_java nio

    Java NIO的核心组件包括通道(Channel)、缓冲区(Buffer)和选择器(Selector)。在本压缩包"java-instantcode-developing.rar_java nio"中,主要探讨的是如何使用Java NIO来开发应用程序。 1. **通道(Channel)**...

    Java-NIO-系列教程

    除了以上提到的 Buffer 类型之外,Java NIO 还提供了一个特殊的 Buffer 类型——`MappedByteBuffer`,用于表示内存映射文件。这种方式能够提高文件的读写效率,但由于其实现较为复杂,本概述中不做详细介绍。 #### ...

    java-Operation-On-Files.rar_operation

    在Java编程语言中,文件操作是一项基础且至关重要的任务,涉及到读取、写入、删除以及缓存管理等多种操作。本资源"java-Operation-On-Files.rar_operation"提供了一组实用的Java源代码示例,专门针对这些常见操作,...

    java 中Buffer源码的分析

    Buffer 是 Java 中一个非常重要的知识点,Direct Buffer 和 Heap Buffer 是两种不同的 Buffer,Direct Buffer 可以提高效率和减少GC 的频率,而 Heap Buffer 需要进行数据复制,因此效率较低。在实际开发中,应该...

    深入浅出MappedByteBuffer.pdf

    《深入浅出MappedByteBuffer》这篇文章主要探讨了Java NIO中MappedByteBuffer这一高效处理大文件的机制,以及与其相关的计算机内存管理概念。首先,我们来详细理解一下这些知识点。 内存管理是计算机系统的重要组成...

    java全栈工程师-java io

    Java IO(Input/Output)是Java编程语言中用于处理输入输出操作的基础模块之一。IO操作是任何程序的重要组成部分,因为几乎所有应用程序都需要读取或写入数据。Java IO提供了丰富的类和接口来处理不同的IO需求,包括...

    Java-SSD3()

    如果“SSD3”与固态硬盘相关,那么这个学习资源可能涵盖了Java如何与硬件设备交互,例如通过JNI(Java Native Interface)调用C/C++库来操作SSD驱动,或者使用Java的FileChannel和MappedByteBuffer进行高效的数据...

    JAVA-NIO程序设计完整实例

    NIO与传统的BIO(Blocking I/O)模型相比,其核心在于它允许程序同时处理多个输入和输出流,提高了并发性能。本实例将深入探讨NIO的基本概念、关键组件以及如何在实际编程中应用NIO。 ### 1. NIO基本概念 - **通道...

    java8源码-netty-learn:这是一个用于netty学习的工程

    java8 源码 netty-learn 这是一个用于netty学习的工程 ##NIO基础 三大组件 Channel & Buffer channel有点类似于stream,它就是读写数据的双向通道,可以从channel将数据读入buffer,也可以将buffer中的数据写入到...

    IBM-ETP-java培训10.Java IO.ppt

    通道(Channel)和缓冲区(Buffer)是NIO的核心概念。 13. **文件观察者**:Java 7引入了Files类和WatchService API,允许程序监听文件系统事件,如文件创建、删除或修改。 14. **内存映射文件**:...

    java io 系列操作代码练习 Java学习资料

    总结,Java IO是Java开发中的基础技能,理解和熟练掌握IO操作对于任何Java开发者都至关重要。通过这个“java io 系列操作代码练习”,你可以系统地学习和实践Java IO的各种操作,从而在实际工作中更加游刃有余。

    Java NIO教程文档

    Java NIO 的核心组件包括 Channel、Buffer 和 Selector。 - **Channel 实现**: - **FileChannel**:用于文件 IO。 - **DatagramChannel**:用于 UDP 网络 IO。 - **SocketChannel**:用于 TCP 网络 IO。 - **...

    基于Java的源码-二进制IO类与文件复制操作实例.zip

    1. **InputStream与OutputStream**: 这是Java IO流的基础类,所有处理二进制数据的输入流和输出流都继承自它们。InputStream代表数据的输入,而OutputStream代表数据的输出。例如,FileInputStream和...

    java nio教程pdf

    Java NIO(New IO,也称为Non-Blocking IO)是一种基于通道(Channel)和缓冲区(Buffer)的I/O操作方法,用于替代标准Java IO API。Java NIO提供了与标准IO不同的I/O工作方式,它是面向缓冲区、基于通道的I/O操作,...

    java代码-门店批量分片

    在Java编程领域,"门店批量分片"通常指的是在处理大量数据时,为了提高效率和降低内存消耗,将数据集分成多个小块(分片)分别处理的技术。这里提到的"java代码-门店批量分片"可能是一个Java程序,用于处理例如门店...

    mmfinvoker:简单的进程间 java 请求-响应库

    NIO的核心组件包括通道(Channel)、缓冲区(Buffer)和选择器(Selector)。在mmfinvoker中,MappedByteBuffer是NIO缓冲区的一个特殊类型,它允许将文件直接映射到Java虚拟机的内存,使得对文件的操作就像操作内存...

    Java nio详细介绍 详细介绍java nio

    **Buffer** 和 **Channel** 是NIO中的两个核心概念。 1. **Buffer是什么?** - **定义**:`Buffer`是一个包含数据的对象,用于读写操作。在NIO中,所有数据的读写都需要通过`Buffer`来进行。 - **特点**:`...

    java io读取文件

    在Java编程语言中,`IO`(Input/Output)是处理数据输入和输出的核心部分,尤其是在处理大数据量文件时显得尤为重要。Java IO API提供了一系列类和接口,使得开发者能够高效地读取、写入和操作文件。下面我们将深入...

Global site tag (gtag.js) - Google Analytics