JAVA NIO BUFFER (九)Direct Buffer

ByteBuffer和其他Buffer不同的是,它们可以作为Channel(通道)操作的起点或者终点。通道只接受ByteBuffer作为参数。

操作系统在内存区中进行IO操作,这些内存区域就是连续的byte。操作系统会直接进入进程的地址空间来转移数据。也就是说内存区的数据最好是连续的字节数。但是在JVM中,字节数组并不一定存储在连续的内存区域,GC可能会移动它们。如何存储数组,根据JVM的实现还有很大的区别。

因为这个原因,引入了direct buffer这一概念,direct buffer来处理通道和本地IO操作。尽最大努力把byte数据存储在一个channel可以直接使用的或者可以直接由本地方法通知操作系统,操作系统直接操作的内存区域。

这往往是IO最高效的选择,支持JVM能支持的最高效IO机制。非直接的Buffer也可以传递给channel,但是会导致性能的损失。通常情况下,非直接的buffer是不可能作为本地IO操作的目标的。如果你将一个非直接buffer传递给channel操作,channel可能会做如下的操作
1.创建一个临时的direct ByteBuffer对象
2.把非直接的ByteBuffer中的内容拷贝到1创建的对象中
3.利用临时对象进行低等级的IO操作
4.临时对象使用完毕,等待GC回收

创建DirectBuffer的代价可能会更高,DirectBuffer使用的内存是越过JVM,直接由本地代码分配的。而且DirectBuffer使用的内存无法被垃圾回收,因为它们在JVM堆之外。

public abstract class ByteBuffer extends Buffer implements Comparable {
  public static ByteBuffer allocate(int capacity)
  public static ByteBuffer allocateDirect(int capacity)
  public abstract boolean isDirect();
}

调用allocateDirect方法来创建一个DirectBuffer。那些根据wrap方法创建的buffer,总是非直接的(non-direct)。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容