Netty中ByteBuf的copy、duplicate、slice方法对比「建议收藏」

Netty中ByteBuf的copy、duplicate、slice方法对比「建议收藏」敬请期待~

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

Jdk注释翻译

/**
*返回ByteBuf的可读字节的拷贝。修改返回的ByteBuf内容与当前ByteBuf完全不会相互影响。
*此方法不会修改当前ByteBuf的readerIndex或writerIndex
**/
public abstract ByteBuf copy();
/**
*返回ByteBuf可读字节的一部分。 修改返回的ByteBuf或当前ByteBuf会影响彼此的内容,
*同时它们维护单独的索引和标记,此方法不会修改当前ByteBuf的readerIndex或writerIndex
*另请注意,此方法不会调用{@link #retain()},因此不会增加引用计数。
**/
public abstract ByteBuf duplicate();
/**
*返回共享当前ByteBuf信息的新ByteBuf,他们使用独立的readIndex writeIndex markIndex
*修改返回的ByteBuf或当前ByteBuf会影响彼此的内容,同时它们维护单独的索引和标记,
*此方法不会修改当前ByteBuf的readerIndex或writerIndex,
*另请注意,此方法不会调用{@link #retain()},因此不会增加引用计数
**/
public abstract ByteBuf slice();

实验验证

public class ByteBufTest {

    public static void main(String[] args) throws UnsupportedEncodingException {
        ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(10);
        byteBuf.writeInt(126);
        byteBuf.writeInt(127);
        byteBuf.writeBytes(new byte[]{1});
        System.out.println("byteBuf readInt="+byteBuf.readInt());
        System.out.println("byteBuf readerIndex=" + byteBuf.readerIndex() + "| writeIndex=" + byteBuf.writerIndex() + "|capacity=" + byteBuf.capacity());
        //返回ByteBuf的可读字节的拷贝。修改返回的ByteBuf内容与当前ByteBuf完全不会相互影响。
        //此方法不会修改当前ByteBuf的readerIndex或writerIndex
        System.out.println("====================byteBuf.copy()==================");
        ByteBuf cByteBuf = byteBuf.copy();
        System.out.println("cByteBuf readerIndex=" + cByteBuf.readerIndex() + "| writeIndex=" + cByteBuf.writerIndex() + "|capacity=" + cByteBuf.capacity());
        System.out.println("byteBuf readerIndex=" + byteBuf.readerIndex() + "| writeIndex=" + byteBuf.writerIndex() + "|capacity=" + byteBuf.capacity());
        System.out.println("向cByteBuf中写入数据" + cByteBuf.setInt(0, 128));
        System.out.println("cByteBuf=" + cByteBuf.getInt(0) + "|cByteBuf=" + cByteBuf.getByte(4));
        System.out.println("byteBuf=" + byteBuf.getInt(0) + "|byteBuf=" + byteBuf.getInt(4) + "|byteBuf=" + byteBuf.getByte(8));
        //返回ByteBuf可读字节的一部分。 修改返回的ByteBuf或当前ByteBuf会影响彼此的内容,
        // 同时它们维护单独的索引和标记,此方法不会修改当前ByteBuf的readerIndex或writerIndex
        //另请注意,此方法不会调用{@link #retain()},因此不会增加引用计数。
        System.out.println("====================byteBuf.slice()==================");
        ByteBuf sByteBuf = byteBuf.slice();
        System.out.println("sByteBuf readerIndex=" + sByteBuf.readerIndex() + "| writeIndex=" + sByteBuf.writerIndex() + "|capacity=" + sByteBuf.capacity());
        System.out.println("byteBuf readerIndex=" + byteBuf.readerIndex() + "| writeIndex=" + byteBuf.writerIndex() + "|capacity=" + byteBuf.capacity());
        System.out.println("向sByteBuf中写入数据" + sByteBuf.setInt(0, 128));
        System.out.println("sByteBuf=" + sByteBuf.getInt(0) + "|sByteBuf=" + sByteBuf.getByte(4));
        System.out.println("byteBuf=" + byteBuf.getInt(0) + "|byteBuf=" + byteBuf.getInt(4) + "|byteBuf=" + byteBuf.getByte(8));
        //返回共享当前ByteBuf信息的新ByteBuf,他们使用独立的readIndex writeIndex markIndex
        //修改返回的ByteBuf或当前ByteBuf会影响彼此的内容,同时它们维护单独的索引和标记,
        // 此方法不会修改当前ByteBuf的readerIndex或writerIndex,
        //另请注意,此方法不会调用{@link #retain()},因此不会增加引用计数。
        System.out.println("====================byteBuf.duplicate()==================");
        ByteBuf dByteBuf = byteBuf.duplicate();
        System.out.println("dByteBuf readerIndex=" + dByteBuf.readerIndex() + "| writeIndex=" + dByteBuf.writerIndex() + "|capacity=" + dByteBuf.capacity());
        System.out.println("byteBuf readerIndex=" + byteBuf.readerIndex() + "| writeIndex=" + byteBuf.writerIndex() + "|capacity=" + byteBuf.capacity());
        System.out.println("向dByteBuf中写入数据" + dByteBuf.setInt(0, 100));
        System.out.println("dByteBuf=" + dByteBuf.getInt(0) + "|dByteBuf=" + dByteBuf.getInt(4) + "|dByteBuf=" + dByteBuf.getByte(8));
        System.out.println("byteBuf=" + byteBuf.getInt(0) + "|byteBuf=" + byteBuf.getInt(4) + "|byteBuf=" + byteBuf.getByte(8));
        dByteBuf.writeBytes(new byte[]{2});
        System.out.println("dByteBuf readerIndex=" + dByteBuf.readerIndex() + "| writeIndex=" + dByteBuf.writerIndex() + "|capacity=" + dByteBuf.capacity());
        System.out.println("byteBuf readerIndex=" + byteBuf.readerIndex() + "| writeIndex=" + byteBuf.writerIndex() + "|capacity=" + byteBuf.capacity());
        System.out.println("dByteBuf=" + dByteBuf.getInt(0) + "|dByteBuf=" + dByteBuf.getInt(4) + "|dByteBuf=" + dByteBuf.getByte(8) + "|dByteBuf=" + dByteBuf.getByte(9));
        System.out.println("byteBuf=" + byteBuf.getInt(0) + "|byteBuf=" + byteBuf.getInt(4) + "|byteBuf=" + byteBuf.getByte(8) + "|byteBuf=" + dByteBuf.getByte(9));
    }

}

执行结果:

byteBuf readInt=126
byteBuf readerIndex=4| writeIndex=9|capacity=10
====================byteBuf.copy()==================
cByteBuf readerIndex=0| writeIndex=5|capacity=5
byteBuf readerIndex=4| writeIndex=9|capacity=10
向cByteBuf中写入数据PooledUnsafeDirectByteBuf(ridx: 0, widx: 5, cap: 5)
cByteBuf=128|cByteBuf=1
byteBuf=126|byteBuf=127|byteBuf=1
====================byteBuf.slice()==================
sByteBuf readerIndex=0| writeIndex=5|capacity=5
byteBuf readerIndex=4| writeIndex=9|capacity=10
向sByteBuf中写入数据UnpooledSlicedByteBuf(ridx: 0, widx: 5, cap: 5/5, unwrapped: PooledUnsafeDirectByteBuf(ridx: 4, widx: 9, cap: 10))
sByteBuf=128|sByteBuf=1
byteBuf=126|byteBuf=128|byteBuf=1
====================byteBuf.duplicate()==================
dByteBuf readerIndex=4| writeIndex=9|capacity=10
byteBuf readerIndex=4| writeIndex=9|capacity=10
向dByteBuf中写入数据UnpooledDuplicatedByteBuf(ridx: 4, widx: 9, cap: 10, unwrapped: PooledUnsafeDirectByteBuf(ridx: 4, widx: 9, cap: 10))
dByteBuf=100|dByteBuf=128|dByteBuf=1
byteBuf=100|byteBuf=128|byteBuf=1
dByteBuf readerIndex=4| writeIndex=10|capacity=10
byteBuf readerIndex=4| writeIndex=9|capacity=10
dByteBuf=100|dByteBuf=128|dByteBuf=1|dByteBuf=2
byteBuf=100|byteBuf=128|byteBuf=1|byteBuf=2

小结:

  • duplicate():直接拷贝整个buffer,包括readerIndex、capacity、writerIndex
  • slice():拷贝buffer中已经写入数据的部分
  • copy()方法会进行内存复制工作,效率很低。

duplicate和copye这两个方法都属于浅拷贝它和原buffer是共享数据的。所以说调用这些方法消耗是很低的,
并没有开辟新的空间去存储,但是修改后会影响原buffer。这就会导致一个问题:在源ByteBuf调用release() 之后,
一旦引用计数为零,就变得不能访问了;在这种场景下,源ByteBuf的所有浅层复制实例也不能进行读写了;如果强行对浅层复制实例进行读写,则会报错。因此,在调用浅层复制实例时,可以通过调用一次retain() 方法来增加引用,表示它们对应的底层内存多了一次引用,引用计数为2。在浅层复制实例用完后,需要调用两次release()方法,将引用计数减一,这样就不影响源ByteBuf的内存释放。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/191970.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • redis实现 spring-redis-data初学习

    redis实现 spring-redis-data初学习

    2021年9月9日
    56
  • 【SQL基础-4】SQL语句练习实例—在SQLzoo平台练习

    目录1平台操作简介2select基本语句2.1第1节selectbasic2.2第1节练习3SELECTfromWORLD练习3.1第2节SELECTfromWORLDTutorial3.2第2节练习4SELECT_from_Nobel练习4.1第3节SELECT_from_Nobel_Tutorial4.2第3节练习5归纳参考文章1平台操作简介本节练习内容主要是该平台左侧红色框内共9节内容,包括对应9节练习。每一节内容和练习完成

    2022年4月13日
    61
  • Java入门——第一个Java程序HelloWorld(Dos命令窗口)

    Java入门——第一个Java程序HelloWorld(Dos命令窗口)麻烦找一个指定盘符的确切文件位置(尽量不要把要运行的.java文件建在桌面上,因为在Dos命令行中找文件路径比较麻烦!),可以创建一个专门用来练习入门Java程序的文件夹。(比如我这个暂时存放.java文件的文件夹在F盘的Java_WorkBenth文件夹里面)1、第一步,打开Windows资源管理器的查看文件后缀名功能(防止出现xxx.java.txt的文件格式)。2、创建一…

    2022年5月28日
    42
  • 经典智能算法之粒子群算法详解

    经典智能算法之粒子群算法详解经典智能算法之粒子群算法要理解粒子群算法怎么可能没有算法背景,请看算法历史粒子群优化(ParticleSwarmOptimization,PSO)算法是Kennedy和Eberhart受人工生命研究结果的启发、通过模拟鸟群觅食过程中的迁徙和群聚行为而提出的一种基于群体智能的全局随机搜索算法。自然界中各种生物体均具有一定的群体行为,而人工生命的主要研究领域之一是探索自然界生物的群体行为…

    2022年6月6日
    124
  • 连接失败连接区间变量

    连接失败连接区间变量

    2022年1月12日
    52
  • 如何用python画心形_用python制作音乐

    如何用python画心形_用python制作音乐用python绘制爱心的基本步骤如下:首先先下载安装好python程序。在我们自己的电脑上找到python的IDLE工具。2.然后打开IDLE,新建一个文件,命名为test1.py。3.接着我们就开始导入turtle库,然后编辑代码。importturtleimporttime#画心形圆弧defhart_arc():foriinrange(200):turtle.right(1)t…

    2025年9月29日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号