Buffer

allocate()

ByteBuffer.allocat()
public static ByteBuffer allocate(int capacity) {
    if (capacity < 0)
        throw new IllegalArgumentException();
    // 堆内缓存区
    return new HeapByteBuffer(capacity, capacity);
}
ByteBuffer.allocateDirect()
public static ByteBuffer allocateDirect(int capacity) {
    // 对外缓存区
    return new DirectByteBuffer(capacity);
}

HeapByteBuffer

内存是分配在堆上的,直接由Java虚拟机负责垃圾收集。

创建HeapByteBuffer
HeapByteBuffer(int cap, int lim) {        
    super(-1, 0, lim, cap, new byte[cap], 0);
}
ByteBuffer
ByteBuffer(int mark, int pos, int lim, int cap,   
             byte[] hb, int offset)
{
    super(mark, pos, lim, cap);
    this.hb = hb;
    this.offset = offset;
}

DirectByteBuffer

是通过JNI在Java虚拟机外的内存中分配了一块(java堆内存由Xmx控制,而堆外内存由-XX:MaxDirectMemorySize控制),该内存块并不直接由Java虚拟机负责垃圾收集,但是在DirectByteBuffer包装类被回收时,会通过Java Reference机制来释放该内存块。

比较

对于HeapByteBuffer,数据的分配存储都在jvm堆上,当需要和io设备打交道的时候,会将jvm堆上所维护的byte[]拷贝至堆外内存,然后堆外内存直接和io设备交互。如果直接使用DirectByteBuffer,那么就不需要拷贝这一步,将大大提升io的效率,这种称之为零拷贝(zero-copy)。

Last updated