公司开发一个商用的支付应用。写协议的时候需要用到byte类型数组来填充协议的报文数据。在调研了JDK各个类库之后,最终选用Java类库中的ByteBuffer。
在Java中,ByteBuffer
是java.nio
包中的一个类,用于处理字节数据。ByteBuffer
提供了两种方式来分配内存:allocate
和allocateDirect
。
/**
* Allocates a new direct byte buffer.
*
* <p> The new buffer's position will be zero, its limit will be its
* capacity, its mark will be undefined, and each of its elements will be
* initialized to zero. Whether or not it has a
* {@link #hasArray backing array} is unspecified.
*
* @param capacity
* The new buffer's capacity, in bytes
*
* @return The new byte buffer
*
* @throws IllegalArgumentException
* If the <tt>capacity</tt> is a negative integer
*/
public static ByteBuffer allocateDirect(int capacity) {
// Android-changed: Android's DirectByteBuffers carry a MemoryRef.
// return new DirectByteBuffer(capacity);
DirectByteBuffer.MemoryRef memoryRef = new DirectByteBuffer.MemoryRef(capacity);
return new DirectByteBuffer(capacity, memoryRef);
}
/**
* Allocates a new byte buffer.
*
* <p> The new buffer's position will be zero, its limit will be its
* capacity, its mark will be undefined, and each of its elements will be
* initialized to zero. It will have a {@link #array backing array},
* and its {@link #arrayOffset array offset} will be zero.
*
* @param capacity
* The new buffer's capacity, in bytes
*
* @return The new byte buffer
*
* @throws IllegalArgumentException
* If the <tt>capacity</tt> is a negative integer
*/
public static ByteBuffer allocate(int capacity) {
if (capacity < 0)
throw new IllegalArgumentException();
return new HeapByteBuffer(capacity, capacity);
}
这两种方式分别对应于不同的内存分配策略,具有不同的优劣势。
allocate
方法分配的内存是在Java虚拟机的堆内存中。ByteBuffer.allocate(capacity)
分配的是非直接缓冲区(non-direct buffer)。```java
ByteBuffer buffer = ByteBuffer.allocate(1024);
```
allocateDirect
方法分配的内存是在操作系统的本地内存中,而不是在Java堆内存中。ByteBuffer.allocateDirect(capacity)
分配的是直接缓冲区(direct buffer)。```java
ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024);
```
选择使用哪种方式取决于应用的需求和性能特征:
allocate: 适用于较小的缓冲区,对内存占用不太敏感的情况。由于是在Java堆上分配,垃圾回收器能够管理这部分内存,但可能会有一些性能开销。
allocateDirect: 适用于需要较大缓冲区或对性能要求较高的情况。由于是在本地内存上分配,可能减少了一些垃圾回收器的开销,但在分配和释放直接缓冲区时可能涉及到一些本地资源的操作。
在使用allocateDirect
时需要谨慎,因为它可能占用较多的本地内存,过度使用可能导致本地内存耗尽。
在选用这两种技术方案中哪一种的时候需要根据具体的应用场景和需求权衡两者之间的取舍。