一、首先是JavaDocument:
直接与 非直接缓冲区
字节缓冲区要么是直接的,要么是非直接的。如果为直接字节缓冲区,则 Java 虚拟机会尽最大努力直接在此缓冲区上执行本机 I/O 操作。也就是说,在每次调用基础操作系统的一个本机 I/O 操作之前(或之后),虚拟机都会尽量避免将缓冲区的内容复制到中间缓冲区中(或从中间缓冲区中复制内容)。
直接字节缓冲区可以通过调用此类的 allocateDirect 工厂方法来创建。此方法返回的缓冲区进行分配和取消分配所需成本通常高于非直接缓冲区。直接缓冲区的内容可以驻留在常规的垃圾回收堆之外,因此,它们对应用程序的内存需求量造成的影响可能并不明显。所以,建议将直接缓冲区主要分配给那些易受基础系统的本机 I/O 操作影响的大型、持久的缓冲区。一般情况下,最好仅在直接缓冲区能在程序性能方面带来明显好处时分配它们。
二、allocateDirect
public static ByteBuffer allocateDirect(int capacity)分配新的直接字节缓冲区。 新缓冲区的位置将为零,其界限将为其容量,其标记是不确定的。无论它是否具有底层实现数组,其标记都是不确定的。
参数:
capacity - 新缓冲区的容量,以字节为单位
返回:
新的字节缓冲区
抛出:
IllegalArgumentException - 如果 capacity 为负整数
再看相关代码:
ByteBuffer 的代码节选:
public static ByteBuffer allocateDirect(int capacity) {
return new DirectByteBuffer(capacity);
}
DirectByteBuffer 的代码节选:
DirectByteBuffer(int cap) { // package-private
super(-1, 0, cap, cap, false);
Bits.reserveMemory(cap);
int ps = Bits.pageSize();
long base = 0;
try {
base = unsafe.allocateMemory(cap + ps);
} catch (OutOfMemoryError x) {
Bits.unreserveMemory(cap);
throw x;
}
unsafe.setMemory(base, cap + ps, (byte) 0);
if (base % ps != 0) {
// Round up to page boundary
address = base + ps - (base & (ps - 1));
} else {
address = base;
}
cleaner = Cleaner.create(this, new Deallocator(base, cap));
}
java使用的是本地方法在管理相对应的内存:
public native long allocateMemory(long _long);
public native void setMemory(long _long, long _long1, byte _byte);
public native void copyMemory(long _long, long _long1, long _long2);
public native void freeMemory(long _long);
三、allocate 方法:
分配一个HeapByteBuffer的实例,其底层是byte数组。
在使用ByteBuffer 分配字节数组的时候,要注意使用!
分享到:
相关推荐
1. **分配缓冲区**:可以通过`ByteBuffer.allocate(int capacity)`来创建一个新的ByteBuffer,其中capacity参数指定缓冲区的大小。 2. **直接缓冲区**:对于性能敏感的应用,可以使用`ByteBuffer.allocateDirect...
2. 使用`ByteBuffer.allocateDirect(int capacity)`:分配一个直接缓冲区,直接缓冲区通常在物理内存中,而不是Java堆上,能提高性能,尤其在处理大文件时。 3. 使用`ByteBuffer.wrap(byte[] array)`:将已有的字节...
- **非直接缓冲区**:由Java堆内存分配空间,通过`ByteBuffer.allocate(int capacity)`方法创建。 - **直接缓冲区**:在本机内存中分配空间,不受垃圾回收器管理,通常比非直接缓冲区更高效,但需谨慎使用。可通过`...
直接缓冲区通过`ByteBuffer.allocateDirect(size)`创建。 - **非直接缓冲区**:这类缓冲区通常位于JVM堆内,数据需要先从物理内存复制到JVM堆中的缓冲区,然后再进行处理,因此性能略低于直接缓冲区。非直接缓冲区...
1. **实例化**:可以通过调用`ByteBuffer.allocate(int capacity)`或`ByteBuffer.allocateDirect(int capacity)`来创建`ByteBuffer`对象。前者创建的是堆内存中的缓冲区,而后者则是直接缓冲区,通常用于频繁读写的...
与`ByteBuffer.allocate()`不同,`allocateDirect()`不会在Java堆上分配内存,而是请求操作系统分配一块连续的物理内存空间。 3. **直接缓冲区与间接缓冲区的区别**: - **内存位置**:间接缓冲区(Heap ...
ByteBuffer wBuffer = ByteBuffer.allocateDirect(bufSize); ``` - 使用`RandomAccessFile`创建`FileChannel`,这种方式支持随机访问文件。 - `ByteBuffer`用于缓存读写操作的数据,`allocateDirect`可以提高...
在Java中,`ByteBuffer.allocateDirect()`方法是用来分配堆外内存的,这个方法实际上创建了一个`DirectByteBuffer`对象。`DirectByteBuffer`是一个Java类,它本身存储在堆内存中,但是通过`native`方法`unsafe....
- `ByteBuffer.allocate(int capacity)`:创建一个具有指定容量的`ByteBuffer`。 - `ByteBuffer.allocateDirect(int capacity)`:创建一个直接的`ByteBuffer`。直接`ByteBuffer`在执行IO操作时通常性能更佳,因为它...
ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024); ``` #### 六、总结 本文档通过对NIO库的详细介绍,旨在帮助Java开发者更好地理解和掌握NIO的核心概念和技术细节。通过学习缓冲区、通道和选择器等关键...
ByteBuffer wBuffer = ByteBuffer.allocateDirect(bufSize); readFileByLine(bufSize, fcin, rBuffer, fcout, wBuffer); System.out.print("读写完成!"); } public static void readFileByLine(int bufSize...
- **字符串类的方法**:介绍了 `String` 类中与正则表达式相关的常用方法。 - **实例应用**:提供了一个面向对象的文件搜索工具示例。 #### 七、字符集(Character Sets) - **基础知识**:介绍了字符集的基本概念...
此外,ByteBuffer还提供了静态方法allocate、allocateDirect等,用于创建堆内或堆外缓冲区,其中堆外缓冲区可以避免频繁的内存复制,提高性能。 在使用NIO时,通常会遵循以下步骤: 1. 创建Buffer,如ByteBuffer。 ...
**分配缓冲器**:通过调用特定类型的缓冲器静态方法(例如`ByteBuffer.allocate(size)`)创建一个缓冲器。 2. **写入数据**:将数据写入缓冲器。 3. **翻转缓冲器**:调用`flip()`方法切换缓冲器状态,使其准备好...
- **分配**:通过静态方法`allocate(int capacity)`创建缓冲区。 - **读写**:通过`put(byte[] src)`将数据写入缓冲区;通过`get()`或`get(byte[] dst)`从缓冲区读取数据。 - **翻转**:通过调用`flip()`方法将...
- **创建缓冲区**:使用静态工厂方法创建缓冲区实例,例如 `ByteBuffer.allocate(1024)` 创建一个容量为 1024 字节的 `ByteBuffer`。 - **操作方法**:`put()` 方法用于向缓冲区写入数据,`get()` 方法用于从缓冲...
- `allocateDirect(int capacity)`:创建一个Direct ByteBuffer,它通常在内存映射文件或直接I/O操作中性能更优。 - `wrap(byte[] array)`:将已存在的字节数组包装成ByteBuffer。 - `wrap(byte[] array, int offset...
缓冲池通过`java.nio.Buffers`类的静态方法创建,例如`allocate()`和`allocateDirect()`。`allocate()`创建的是堆缓冲区,而`allocateDirect()`创建的是直接缓冲区,后者能避免Java对象与操作系统之间的数据复制,...
实例化ByteBuffer有两种主要方式:allocate()用于在堆上分配内存,而allocateDirect()则是在堆外直接分配,适用于需要高效访问和多次复用的情况。ByteBuffer还可以通过wrap()方法从byte数组中创建,或者通过put()...