目录
HeapByteBuffer与DirectByteBuffer的区别
Buffer简介
缓冲区(Buffer)就是在内存中预留指定大小的存储空间用来对输入/输出(I/O)的数据作临时存储,对数据进行存取,这部分预留的内存空间就叫做缓冲区。
缓冲区就是数组,用于存储不同类型的数据。根据数据类型不同,提供了相应的类型的缓冲区(boolean类型除外)
使用缓冲区有这么两个好处:
1、减少实际的物理读写次数
2、缓冲区在创建时就被分配内存,这块内存区域一直被重用,可以减少动态分配和回收内存的次数
Buffer 主要属性
0<<=position<=limit<=capacity
-1<=mark<=position<=limit<=capacity
属性 | 描述 |
---|---|
Capacity | 容量,即可以容纳的最大数据量;在缓冲区创建时被设定并且不能改变 |
Limit | 表示缓冲区的当前终点,不能对缓冲区超过极限的位置进行读写操作。且极限是可以修改的 |
Position | 位置,下一个要被读或写的元素的索引,每次读写缓冲区数据时都会改变改值,为下次读写作准备 |
Mark | 标记,调用mark()来设置mark=position,再调用reset()可以让position恢复到标记的位置 |
获取Buffer对象的4种方式
java.nio.Buffer类是一个抽象类,不能被实例化。Buffer类的直接子类,如ByteBuffer等也是抽象类,所以也不能被实例化。但是ByteBuffer类提供了4个静态工厂方法来获得ByteBuffer的实例:
方法 | 说明 |
---|---|
allocate(int capacity) | 从堆空间中分配一个容量大小为capacity的byte数组作为缓冲区的byte数据存储器 |
allocateDirect(int capacity) | 是不使用JVM堆栈,而是通过操作系统来创建内存块用作缓冲区,建立在物理内存中。它与当前操作系统能够更好的耦合,因此能进一步提高I/O操作度。但是分配直接缓冲区的系统开销很大,因此只有在缓冲区较大并长期存在,或者需要经常重用时,才使用这种缓冲区 |
wrap(byte[] array) | 这个缓冲区的数据会存放在byte数组中,bytes数组或buff缓冲区任何一方中数据的改动都会影响另一方。其实ByteBuffer底层本来就有一个bytes数组负责来保存buffer缓冲区中的数据,通过allocate方法系统会帮你构造一个byte数组 |
wrap(byte[] array,int offset, int length) | 在上一个方法的基础上可以指定偏移量和长度,这个offset也就是包装后byteBuffer的position,而length呢就是limit-position的大小,从而我们可以得到limit的位置为length+position(offset) |
Buffer 的常用方法
mark():记录当前position的位置,