简述
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
相关推荐
- **Direct vs Non-Direct Buffer**: Direct Buffer直接映射到物理内存,Non-Direct Buffer在JVM堆上分配内存。 **3. Buffer的日常操作** - **put**: 向Buffer写入数据。 - **get**: 从Buffer读取数据。 - **flip*...
Java NIO的核心组件包括通道(Channel)、缓冲区(Buffer)和选择器(Selector)。在本压缩包"java-instantcode-developing.rar_java nio"中,主要探讨的是如何使用Java NIO来开发应用程序。 1. **通道(Channel)**...
除了以上提到的 Buffer 类型之外,Java NIO 还提供了一个特殊的 Buffer 类型——`MappedByteBuffer`,用于表示内存映射文件。这种方式能够提高文件的读写效率,但由于其实现较为复杂,本概述中不做详细介绍。 #### ...
在Java编程语言中,文件操作是一项基础且至关重要的任务,涉及到读取、写入、删除以及缓存管理等多种操作。本资源"java-Operation-On-Files.rar_operation"提供了一组实用的Java源代码示例,专门针对这些常见操作,...
Buffer 是 Java 中一个非常重要的知识点,Direct Buffer 和 Heap Buffer 是两种不同的 Buffer,Direct Buffer 可以提高效率和减少GC 的频率,而 Heap Buffer 需要进行数据复制,因此效率较低。在实际开发中,应该...
《深入浅出MappedByteBuffer》这篇文章主要探讨了Java NIO中MappedByteBuffer这一高效处理大文件的机制,以及与其相关的计算机内存管理概念。首先,我们来详细理解一下这些知识点。 内存管理是计算机系统的重要组成...
Java IO(Input/Output)是Java编程语言中用于处理输入输出操作的基础模块之一。IO操作是任何程序的重要组成部分,因为几乎所有应用程序都需要读取或写入数据。Java IO提供了丰富的类和接口来处理不同的IO需求,包括...
如果“SSD3”与固态硬盘相关,那么这个学习资源可能涵盖了Java如何与硬件设备交互,例如通过JNI(Java Native Interface)调用C/C++库来操作SSD驱动,或者使用Java的FileChannel和MappedByteBuffer进行高效的数据...
NIO与传统的BIO(Blocking I/O)模型相比,其核心在于它允许程序同时处理多个输入和输出流,提高了并发性能。本实例将深入探讨NIO的基本概念、关键组件以及如何在实际编程中应用NIO。 ### 1. NIO基本概念 - **通道...
java8 源码 netty-learn 这是一个用于netty学习的工程 ##NIO基础 三大组件 Channel & Buffer channel有点类似于stream,它就是读写数据的双向通道,可以从channel将数据读入buffer,也可以将buffer中的数据写入到...
通道(Channel)和缓冲区(Buffer)是NIO的核心概念。 13. **文件观察者**:Java 7引入了Files类和WatchService API,允许程序监听文件系统事件,如文件创建、删除或修改。 14. **内存映射文件**:...
总结,Java IO是Java开发中的基础技能,理解和熟练掌握IO操作对于任何Java开发者都至关重要。通过这个“java io 系列操作代码练习”,你可以系统地学习和实践Java IO的各种操作,从而在实际工作中更加游刃有余。
Java NIO 的核心组件包括 Channel、Buffer 和 Selector。 - **Channel 实现**: - **FileChannel**:用于文件 IO。 - **DatagramChannel**:用于 UDP 网络 IO。 - **SocketChannel**:用于 TCP 网络 IO。 - **...
1. **InputStream与OutputStream**: 这是Java IO流的基础类,所有处理二进制数据的输入流和输出流都继承自它们。InputStream代表数据的输入,而OutputStream代表数据的输出。例如,FileInputStream和...
Java NIO(New IO,也称为Non-Blocking IO)是一种基于通道(Channel)和缓冲区(Buffer)的I/O操作方法,用于替代标准Java IO API。Java NIO提供了与标准IO不同的I/O工作方式,它是面向缓冲区、基于通道的I/O操作,...
在Java编程领域,"门店批量分片"通常指的是在处理大量数据时,为了提高效率和降低内存消耗,将数据集分成多个小块(分片)分别处理的技术。这里提到的"java代码-门店批量分片"可能是一个Java程序,用于处理例如门店...
NIO的核心组件包括通道(Channel)、缓冲区(Buffer)和选择器(Selector)。在mmfinvoker中,MappedByteBuffer是NIO缓冲区的一个特殊类型,它允许将文件直接映射到Java虚拟机的内存,使得对文件的操作就像操作内存...
**Buffer** 和 **Channel** 是NIO中的两个核心概念。 1. **Buffer是什么?** - **定义**:`Buffer`是一个包含数据的对象,用于读写操作。在NIO中,所有数据的读写都需要通过`Buffer`来进行。 - **特点**:`...
在Java编程语言中,`IO`(Input/Output)是处理数据输入和输出的核心部分,尤其是在处理大数据量文件时显得尤为重要。Java IO API提供了一系列类和接口,使得开发者能够高效地读取、写入和操作文件。下面我们将深入...