Java中HeapByteBuffer和DirectByteBuffer的区别

x33g5p2x  于2021-10-28 转载在 Java  
字(0.7k)|赞(0)|评价(0)|浏览(444)

HeapByteBuffer 和 DirectByteBuffer 都是申请一块内存,只不过HeapByteBuffer是在Java的堆内存中申请,而DirectByteBuffer是在JVM外部申请。

有什么区别呢?

我们都知道JVM会对 堆区 进行GC,会移动存活对象在内存中的位置,HeapByteBuffer也不例外,也会被移动位置。

而DirectByteBuffer由于是在JVM外部,所以不会收到JVM的GC影响。

这个差别就体现在了IO上边。

如果将HeapByteBuffer中的数据写入的时候,JVM会首先在JVM外部申请一个内存,将要写入的数据拷贝到JVM外部申请的内存中,然后将JVM外部内存中的数据写入到磁盘或者网卡中。 对于读取会将数据写入到JVM外部内存中,然后将数据拷贝到HeapByteBuffer中。

为什么要多此一举呢?

因为Java无法直接调用硬件读取或者写入。只能通过内核提供的read()和write()方法,read()和write()需要提供数据对应的内存地址,并且这个地址不能变,如果变了,数据写入或者读取不就错误了嘛。

你可能会说,地址怎么会变呢?这就跟JVM的GC有关了,GC会移动对象在内存中的地址,当地址发生变换的时候,JVM内部的程序是知道的,但是操作系统内核是不知道的。所以不能直接将JVM 堆内的数据直接读取或者写入,需要将堆内的数据拷贝到JVM外部。

由于DirectByteBuffer本身就是在JVM外部申请的内存,所以可以直接进行读取或者写入。

所以,由于JVM的GC机制,HeapByteBuffer在IO的时候,需要额外的内存拷贝,内存拷贝是通过CPU寄存器拷贝的,效率十分低下,所以我们在涉及到IO的时候,尽量使用DirectByteBuffer.

相关文章