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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • linux struts2漏洞,Struts2漏洞分析,漏洞波及全系版本

    linux struts2漏洞,Struts2漏洞分析,漏洞波及全系版本Struts漏洞分析ApacheStruts团队已经发布了Struts2.3.15.1安全更新版本。在Struts2.3.15.1版本之前,存在着严重的安全漏洞,如果现在一些比较大的网站是用JAVA做的,没有把版本升级,还用的是Strtus2.3.15.1版本之前的话,那么你们就要小心,服务器被黑了哦。下面就来说一下之前版本,Struts2的漏洞是如何产生的,我们自己去做,该如何的去解决这个…

    2022年7月19日
    13
  • spring starter(怎么编写自己的starter)

    微服务架构从本质上说其实就是分布式架构,与其说是一种新架构,不如说是一种微服务架构风格。简单来说,微服务架构风格是要开发一种由多个小服务组成的应用。每个服务运行于独立的进程,并且采用轻量级交互。多数情况下是一个HTTP的资源API。这些服务具备独立业务能力并可以通过自动化部署方式独立部署。这种风格使最小化集中管理,从而可以使用多种不同的编程语言和数据存储技术。对于微服务架构系统,由于其服务粒度…

    2022年4月10日
    57
  • storm源代码分析—Transactional spouts

    storm源代码分析—Transactional spouts

    2022年1月30日
    36
  • mysql如何查询前10个数据_查询前十条数据

    mysql如何查询前10个数据_查询前十条数据要选择前10条记录,请在MySQL中使用LIMIT。让我们首先创建一个表-mysql>createtableDemoTable->(->PageNumbertext->);使用插入命令在表中插入一些记录-mysql>insertintoDemoTablevalues(‘Page-1’);mysql>insertintoDemoTabl…

    2022年9月7日
    0
  • SQL Server 存储过程

    SQL Server 存储过程

    2021年8月29日
    51
  • 大数运算C语言实现

    大数运算C语言实现大数乘法利用字符数组进行大数乘法的位运算#include<stdio.h>#include<math.h>#include<string.h>voidprint_cheng(chars1[],chars2[]);voidmain(){chars1[1000],s2[1000];while(scanf(“%s%s”,s1,s2))pr…

    2022年10月7日
    3

发表回复

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

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