我们经常使用ByteBuffer。
通俗的Non-DerictedByteBuffer结构如下
HeapByteBuffer extends ByteBuffer {
Byte[] array;
int pos,limit,cap,mark;
}
通俗的DirectByteBuffer结构如下
DirectByteBuffer extends ByteBuffer {
int address;
int pos,limit,cap,mark;
}
可见直接缓冲使用的是JNI的一个内存地址,因此在释放Buffer时,通过gc是无法释放的,需要JNI。
DirectByteBuffer 的好处是什么呢?
一般的nonDirectBuffer-socket通讯过程中需要,socket -> DirectByteBuffer -> UserheapByteBuffer -> DirectByteBuffer -> socket
因此需要2次copy. copy本身不耗费多长时间,但是建立DirectByteBuffer的时间比较久(JNI调用)。而是用DirectByteBuffer的通讯过程如下
socket -> UserDirectByteBuffer -> socket 可见基本是0-copy (如netty中的compositeBuffer)。
而且在做socketChannel中的
write(ByteBuffer) 和 read(ByteBuffer) 两个方法中 sun的实现已经缓存了所需要的DirectByteBuffer
而 write(ByteBUffer[]) 和 read(ByteBuffer[]) 这种聚集Buffer操作则每次都需要大量时间重新创建DirectByteBuffer
因此当网络IO规模大的时候建议使用DirectBuffer,其他一般情况使用NonDirectBuffer即可。