关于JDK中的ByteBuffer与Netty中的ByteBuf的对比

JDK中ByteBuffer的缺点

  1. 只是用一个标志位position来进行读写标记,读写操作要使用flip方法进行切换,不太友好。
  2. 因为ByteBuffer中的实际存储数据的数组是使用final修饰符修饰的,所以不可以 在原来buffer的基础上动态扩容或者缩小。如果需要扩容,需要另外新建一个ByteBuffer,并将旧的ByteBuffer里面的数组复制到已经扩容的ByteBuffer.
     final byte[] hb;

Netty中的ByteBuf则完全对JDK中的ByteBuffer的缺点进行了改进

  1. 使用readerIndex和writerIndex分别维护读操作和写操作,实现读写索引分离,更加直观。
    byte[] array;
  2. ByteBuf使用的底层数据维护数组没有使用final关键字,所以存在直接在原来ByteBuf进行扩容的可能,而这件事,Betty已经为我们完成,封装在它的write系列方法当中。但是它也存在着一个上限,这个上限就是Integer.MAX_VALUE.
        public ByteBuf writeByte(int value) {
            ensureWritable0(1);//用于验证可写字节长度是否大于将要写入的字节长度。
            _setByte(writerIndex++, value);//写入一个字节并且索引加一的操作。
            return this;
        }
        final void ensureWritable0(int minWritableBytes) {
            ensureAccessible();//验证ByteBuf中的引用计数是否为零,为真则抛出异常,违背了Netty对于垃圾回收的约定
            if (minWritableBytes <= writableBytes()) {//验证可写字节长度是否大于将要写入的字节长度。
                return;//如果是大于,则什么都不做,直接返回
            }
            //如果可写字节长度小于将要写入的最小字节长度,则需要进行扩容
            if (minWritableBytes > maxCapacity - writerIndex) {//判断如果将要到达最大的上限,则抛出异常
                throw new IndexOutOfBoundsException(String.format(
                        "writerIndex(%d) + minWritableBytes(%d) exceeds maxCapacity(%d): %s",
                        writerIndex, minWritableBytes, maxCapacity, this));
            }
    
            // Normalize the current capacity to the power of 2.//如果可写字节长度小于将要写入的最小字节长度,并且没有达到最大上限,
            int newCapacity = alloc().calculateNewCapacity(writerIndex + minWritableBytes, maxCapacity);//计算扩容后capacity
            //扩容的当前capactiy的两倍。
            // Adjust to the new capacity.
            capacity(newCapacity);//重新设置capactiy.并进行数组的重新拷贝
        }

        public ByteBuf capacity(int newCapacity) {
            checkNewCapacity(newCapacity);//验证新生成的capacity是否大于最大整数,是则抛出异常
    
            int oldCapacity = array.length;
            byte[] oldArray = array;
            if (newCapacity > oldCapacity) {
                byte[] newArray = allocateArray(newCapacity);//新建一个新的数组,数组长度为新创建capacity
                System.arraycopy(oldArray, 0, newArray, 0, oldArray.length);//进行旧数组中的数组拷贝到新数组中
                setArray(newArray);//将当前buffer中的array指向新数组
                freeArray(oldArray);//释放掉旧数组
            } else if (newCapacity < oldCapacity) {
                byte[] newArray = allocateArray(newCapacity);
                int readerIndex = readerIndex();
                if (readerIndex < newCapacity) {
                    int writerIndex = writerIndex();
                    if (writerIndex > newCapacity) {
                        writerIndex(writerIndex = newCapacity);
                    }
                    System.arraycopy(oldArray, readerIndex, newArray, readerIndex, writerIndex - readerIndex);
                } else {
                    setIndex(newCapacity, newCapacity);
                }
                setArray(newArray);
                freeArray(oldArray);
            }
            return this;
        }



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值