ByteBuffer
Java 中的示例应用程序是什么?请列出使用此示例的任何示例方案。谢谢!
ByteBuffer
Java 中的示例应用程序是什么?请列出使用此示例的任何示例方案。谢谢!
Answers:
这是对它的用途和缺点的很好的描述。本质上,只要需要执行快速的低级I / O,就可以使用它。如果要实现TCP / IP协议,或者正在编写数据库(DBMS),则该类将派上用场。
ByteBuffer类很重要,因为它构成了Java中使用通道的基础。ByteBuffer类定义了对字节缓冲区的六类操作,如Java 7文档中所述:
Example code : Putting Bytes into a buffer.
// Create an empty ByteBuffer with a 10 byte capacity
ByteBuffer bbuf = ByteBuffer.allocate(10);
// Get the buffer's capacity
int capacity = bbuf.capacity(); // 10
// Use the absolute put(int, byte).
// This method does not affect the position.
bbuf.put(0, (byte)0xFF); // position=0
// Set the position
bbuf.position(5);
// Use the relative put(byte)
bbuf.put((byte)0xFF);
// Get the new position
int pos = bbuf.position(); // 6
// Get remaining byte count
int rem = bbuf.remaining(); // 4
// Set the limit
bbuf.limit(7); // remaining=1
// This convenience method sets the position to 0
bbuf.rewind(); // remaining=7
使用面向流的API的Java IO使用缓冲区作为用户空间内数据的临时存储来执行。通过DMA从磁盘读取的数据首先复制到内核空间的缓冲区中,然后再传输到用户空间的缓冲区中。因此存在开销。避免使用它可以显着提高性能。
如果有一种方法可以直接访问内核空间中的缓冲区,则可以跳过用户空间中的该临时缓冲区。Java NIO提供了一种方法。
ByteBuffer
是Java NIO提供的几个缓冲区之一。它只是一个用于读取数据或向其中写入数据的容器或容纳槽。通过allocateDirect()
在Buffer上使用API 分配直接缓冲区来实现上述行为。
这是一篇很棒的文章,解释了ByteBuffer的好处。以下是本文的重点:
以下是专门针对直接ByteBuffer / MappedByteBuffer的好处。请注意,直接缓冲区是在堆外部创建的:
不受gc周期的影响:直接缓冲区在垃圾回收周期中不会移动,因为它们位于堆外部。TerraCota的BigMemory缓存技术似乎在很大程度上依赖于此优势。如果它们在堆上,则会降低gc暂停时间。
性能提升:在流IO中,读取调用将需要系统调用,这需要在用户模式与内核模式之间进行上下文切换,反之亦然,这将是昂贵的,尤其是在不断访问文件的情况下。但是,使用内存映射可以减少上下文切换,因为更可能在内存中找到数据(MappedByteBuffer)。如果内存中有可用数据,则无需调用操作系统即可直接访问数据,即无需上下文切换。
请注意,MappedByteBuffers非常有用,尤其是在文件较大且很少访问几组块的情况下。