ByteBuffer 直接缓冲区和非直接缓冲区

本文详细介绍了Java中的ByteBuffer,包括直接缓冲区和非直接缓冲区的区别,以及它们在内存中的分配。ByteBuffer通过allocate、allocateDirect和wrap方法创建,其中allocateDirect创建的直接缓冲区在IO操作中速度更快,但创建和回收成本高。另外,文章还讨论了ByteBuffer的重要属性如position、limit和capacity,以及put、get、flip、clear、compact等方法的使用和注意事项。
摘要由CSDN通过智能技术生成


ByteBuffer 直接缓冲区和非直接缓冲区

ByteBuffer 在平时工作中可能用到的不多,但是面试中经常会被问到。本文总结了一些关于 ByteBuffer 的用法和相关 API 介绍。

下面是创建ByteBuffer对象的几种方式:

static ByteBuffer allocate(int capacity)
static ByteBuffer allocateDirect(int capacity)
static ByteBuffer wrap(byte[] array)
static ByteBuffer wrap(byte[] array, int offset, int length)

allocate方式创建的ByteBuffer对象我们称之为非直接缓冲区,这个ByteBuffer对象(和对象包含的缓冲数组)都位于JVM的堆区。wrap方式和allocate方式创建的ByteBuffer没有本质区别,都创建的是非直接缓冲区。

allocateDirect方法创建的ByteBuffer我们称之为直接缓冲区,此时ByteBuffer对象本身在堆区,而缓冲数组位于非堆区, ByteBuffer对象内部存储了这个非堆缓冲数组的地址。在非堆区的缓冲数组可以通过JNI(内部还是系统调用)方式进行IO操作,JNI不受gc影响,机器码执行速度也比较快,同时还避免了JVM堆区与操作系统内核缓冲区的数据拷贝,所以IO速度比非直接缓冲区快。然而allocateDirect方式创建ByteBuffer对象花费的时间和回收该对象花费的时间比较多,所以这个方法适用于创建那些需要重复使用的缓冲区对象。

ByteBuffer 属性和方法

ByteBuffer对象三个重要属性 position, limit和capacity。其中capacity表示了缓冲区的总容量,始终保持不变,初始时候position 等于 0 , limit 等于 capacity。

put:向缓冲区放入数据

abstract ByteBuffer put(byte b)
ByteBuffer put(byte[] src)
ByteBuffer put(byte[] src, int offset, int length)

调用put方法前,limit应该等于capacity,如果不等于,几乎可以肯定我们对缓冲区的操作有误。在put方法中0到position-1的区域表示有效数据,position到limit之间区域表示空闲区域。put方法会从position的当前位置放入数据,每放入一个数据position增加1,当position等于limit(即空闲区域使用完)时还继续放入数据就会抛出BufferUnderflowException异常

get:从缓冲区读取数据

abstract byte get()
ByteBuffer get(byte[] dst)
ByteBuffer get(byte[] dst, int offset, int length)

在get方法中, 0到position-1的区域表示已读数据,position到limit之间的区域表示未读取的数据。每读取一个数据position增加1,当position等于limit时继续读取数据就会抛出BufferUnderflowException异常。

flip :将写模式转换成读模式

public 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值