netty io.netty.buffer简介

io.netty.util.ReferenceCounted

此接口代表一个引用计数的对象,此对象需要显示的释放.

当一个ReferenceCounted对象被实例化的时候,该对象的引用数量就是1,调用retain()方法会增加引用数量,调用 release()
方法会减少引用数量,如果引用数量减少到0,该对象就需要显示释放掉。访问释放掉的对象通常会导致访问冲突。

如果实现ReferenceCounted接口的对象是一个包含同样实现ReferenceCounted接口的对象的容器。当容器的引用数量变为0的时候,容器中的对象也要通过release()方法来释放掉。

主要方法:

int refCnt(); //返回当前对象的引用数量,如果返回零,说明当前对象已经被释放掉了
ReferenceCounted retain();//引用数量增加1
ReferenceCounted retain(int increment);//引用计数增加给定值increment
ReferenceCounted touch();\\此方法记录对象的当前访问位置,主要用来调试。如果确定当前对象内存泄露,通过此操作记
\\录的信息将通过ResourceLeakDetector提供给你
ReferenceCounted touch(Object hint);\\此方法记录对象的当前访问位置并附加一个hint对象,主要用来调试。如果
\\确定当前对象内存泄露,通过此操作记录的信息将通过ResourceLeakDetector提供给你
boolean release();\\引用计数减1,如果引用计数变为0了,则显示的释放掉该对象,当且仅当引用计数变为0且该对象已
\\被释放掉才返回ture,否则返回false
boolean release(int decrement);\\引用计数减少给定值decrement,如果引用计数变为0了,则显示的释放掉该对象,
当且仅当引用计数变为0且该对象已被释放掉才返回ture,否则返回false

io.netty.buffer.ByteBuf

这是一个随机和顺序访问的序列其包含0或者多个字节,此接口为一个或者多字节数组和NIO buffers提供了一个抽象试图

  • 创建buffer

    建议使用辅助方法创建一个新的缓冲区不要调用具体实现的构造函数。

  • 随进访问索引

    就像普通的byte数组一样ByteBuf使用基于0的索引,也就是第一个的索引是0最后一个元素的索引是capacity-1,下面举例迭代访问buffer中的所有字节,做如下操作的时候你可以忽略其内部实现:

ByteBuf buffer = ...;
 for (int i = 0; i < buffer.capacity(); i ++) {
     byte b = buffer.getByte(i);
     System.out.println((char) b);
 }
  • 顺序访问索引

    ByteBuf 提供了两个指针变量来分别支持读和写操作, readerIndex 用于读操作writerIndex 用于写操作. 下面的图展示了一个buffer使如何被两个指针分割成三个区域的:

      +-------------------+------------------+------------------+
      | discardable bytes |  readable bytes  |  writable bytes  |
      |                   |     (CONTENT)    |                  |
      +-------------------+------------------+------------------+
      |                   |                  |                  |
      0      <=      readerIndex   <=   writerIndex    <=    capacity

discardable bytes代表可废弃的区域,readable bytes代码可读区域,writable bytes代表可写区域 readerIndex代表读的起点,writerIndex代表写的起点,capacity代表容量

  • 可读区域(实际内容)

这个区域存储的是实际的数据或者叫有效的数据.  任何以read或者skip开头的操作(任何是指本类中的任何方法)都会得到或者跳过当前readerIndex指示的数据,并且readerIndex会根据读取或者跳过的字节数自增。如果读取         操作的参数也是一个Byte并且没有指定目标ByteBuf的起始index,则该参数ByteBuf的writerIndex也要跟着一起增长。

如果没有足够的数据供读取则报IndexOutOfBoundsException。新分配、wrapped或者拷贝的buffer,其readerIndex是0.相关读取操作如下:

 // Iterates the readable bytes of a buffer. ByteBuf buffer = ...;
 while (buffer.readable()) {
     System.out.println(buffer.readByte());
 }
  • 可写数据区域

    此区域是未定义的区域也就是需要往里面写数据的区域。任何以write开始的操作(任何是指本类中的任何方法)将会从writerIndex开始写数据,并且writerIndex会根据写入的数量增加。如果write操作的参数也是一个ByteBuf并且没有制定源Buff的开始index, 那么该参数ByteBuf的readerInx也要跟着一起增长.

    如果没有足够的空间供写入报IndexOutOfBoundsException,新分配的buffer的writerIndex是0.   wrapped 或者copy的 bufferwriterIndex 等于capacity。写入操作代码:

// Fills the writable bytes of a buffer with random integers. ByteBuf buffer = ...;
 while (buffer.maxWritableBytes() >= 4) {
     buffer.writeInt(random.nextInt());
 }
  • 可废弃区域

这个区域包含的是通过读操作读完的数据区域.初始状态这个区域的大小是0, 随着读操作的调用这个区域会增长到writerIndex的大小. 读过的数据可以通过调用discardReadBytes()方法回收该区域,该方法的功能如下:

BEFORE discardReadBytes()//操作前

      +-------------------+------------------+------------------+
      | discardable bytes |  readable bytes  |  writable bytes  |
      +-------------------+------------------+------------------+
      |                   |                  |                  |
      0      <=      readerIndex   <=   writerIndex    <=    capacity

  AFTER discardReadBytes()//操作后

      +------------------+--------------------------------------+
      |  readable bytes  |    writable bytes (got more space)   |
      +------------------+--------------------------------------+
      |                  |                                      |
 readerIndex (0) <= writerIndex (decreased)        <=        capacity

    需要注意的是,不能保证可写区域的数据内容,可写区域的内容多数情况下不会跟着移动,甚至有可能被不同的数据填充,这依赖于具体的buffer实现。

  • 清空缓冲索引

你可以通过调用clear()方法来将readerIndexwriterIndex 设置为 0. 但是不会清除内容,而只是重置了两个指针.  注意这里的clear()方法语义和java.nio.Buffer.clear()语义是不一样的。

BEFORE clear()

      +-------------------+------------------+------------------+
      | discardable bytes |  readable bytes  |  writable bytes  |
      +-------------------+------------------+------------------+
      |                   |                  |                  |
      0      <=      readerIndex   <=   writerIndex    <=    capacity

  AFTER clear()

      +---------------------------------------------------------+
      |             writable bytes (got more space)             |
      +---------------------------------------------------------+
      |                                                         |
      0 = readerIndex = writerIndex            <=            capacity
  • search相关操作

对于简单的字节搜索,使用 indexOf(int, int, byte)bytesBefore(int, int, byte). bytesBefore(byte). 对于复杂的搜索使用 forEachByte(int, int, ByteBufProcessor)方法,该方法需要一个     ByteBufProcessor 的实现类.

  • 标记和充值 (mark reset)

每个buffer有两个marker indexes. 一个用来存储 readerIndex 另一个用来存储 writerIndex.  可以通过调用reset方法重置,其工作方式类似于InputStream中的mark和reset方法,不同的是其没有readlimit参数.

  • 派生缓冲区(Derived buffers)

你可以通过调用方法duplicate(), slice() or slice(int, int)来根据现有buffer创建一个试图(view) . 一个派生的buffer会有一个独立的readerIndex, writerIndex 和 marker indexes,同时会共享内部数据,这和Java NIO一样.如果要完整拷贝一个buffer,需要调用copy() 方法.

  • 转换成现有的JAVA类型
    • Byte array

      如果ByteBuf内部实现是一个byte[], 可以通过调用array() 方法来访问数组.  判断是否是byte[]可以调用 hasArray()方法.

      NIO Buffers

      通过调用nioBuffer()方法可以得到一个NIO buffer,判断能否进行转换可以调用nioBufferCount()方法.

      Strings

      可以调用提供的多个 toString(Charset) 方法将 ByteBuf 转换为 String.  需要注意的是,toString() 不是转换方法,而是继承Object的toString()方法

      I/O Streams

      参考 ByteBufInputStreamByteBufOutputStream.

io.netty.buffer.ByteBufAllocator

    该接口的实现类负责创建buffer,接口实现类必须是线程安全的。

io.netty.buffer.ByteBufHolder

发送接收的数据包

io.netty.buffer.AbstractByteBuf

实现bytebuf的一个骨架

io.netty.buffer.AbstractByteBufAllocator

ByteBufAllocator的骨架

io.netty.buffer.AbstractDerivedByteBuf

Bytebuf的一个抽象基类,其主要功能是实现了能够封装另一个Bytebuf

io.netty.buffer.AbstractReferenceCountedByteBuf

ByteBuf的一个抽象基类,主要功能是实现了引用计数的功能,即ReferenceCounted借口的功能(retain和release、touch方法)

io.netty.buffer.ByteBufInputStream

继承了InputStream类,该类可以从ByteBuf中读取数据,对该对象进行读操作的时候内部buffer的readerIndex也会增加,需要注意的是读取的字节数量在初始化该对象的时候已经确定了(构造函数内部,初始化的时候已经和设置了长度),后面在对该buffer写数据,对该对象来讲,不会读到。

改流还是DataInput借口,字节的序列并不总是大端序列(big endian),这取决于内部buffer实现

io.netty.buffer.ByteBufOutputStream

继承了OutputStream类,该类可以向ByteBuf中写数据,对该对象进行写操作的时候内部buffer的writerindex也会增加,改流还是DataOutput借口,字节的序列并不总是大端序列(big endian),这取决于内部buffer实现

io.netty.buffer.ByteBufUtil

这是一个处理ByteBuf对象的一些方法的工具类.

io.netty.buffer.CompositeByteBuf

这是一个虚拟bufer,实际上是一个组合buffer,其内部封装了多个buffer,其功能就是将多个buffer组合成一个buffer,推荐使用ByteBufAllocator.compositeBuffer() 或者Unpooled.wrappedBuffer(ByteBuf...)来创建CompositeByteBuf对象,不要直接调用构造函数来创建对象

io.netty.buffer.DefaultByteBufHolder

ByteBufHolder的默认实现,期功能就是把数据存储在bytebuf中

io.netty.buffer.DuplicatedByteBuf

一个派生buffer,简单的把所有的数据访问请求发送给内部的buffer。简易通过ByteBuf.duplicate()方法来创建该对象。该对象与其内部bufer共享数据,只不过二者的readerindex和writerindex是独立的。

io.netty.buffer.EmptyByteBuf

这是一个空的ByteBuf,容量是0

io.netty.buffer.PooledByteBufAllocator

带缓冲的ByteBufAllocator

io.netty.buffer.ReadOnlyByteBuf

这个一个派生buffer,他禁止写操作发送给内部buffer,简易通过 Unpooled.unmodifiableBuffer(ByteBuf) 方法来创建对象

io.netty.buffer.SliceByteBuf

    一个派生buffer,他的功能是仅仅暴露内部buffer的一个自区域,就是切片,推荐通过ByteBuf.slice() andByteBuf.slice(int, int)方法来创建对象

io.netty.buffer.SwappedByteBuf

一个包装buffer,其功能是交换bytebuf的字节序列,即大端序列和小端序列的转换

io.netty.buffer. Unpooled

io.netty.buffer.UnpooledByteBufAllocator

带缓冲的ByteBufAllocator

io.netty.buffer.UnpooledDirectByteBuf

基于NIO ByteBuffer的ByteBuf,推荐通过调用Unpooled.directBuffer(int)或者Unpooled.wrappedBuffer(ByteBuffer)方法来创建对象

io.netty.buffer.UnpooledHeapByteBuf

大端序列的java堆buffer实现

io.netty.buffer.Unpooled

相当于一个工具类,可以创建Bytebuf


时间: 2024-10-07 09:11:39

netty io.netty.buffer简介的相关文章

netty io.netty.channel介绍2

Interface ChannelHandlerContext 上下文对象使得当前channelhandler可以与其所属的channelpipeline以及其他handler进行交互,可以通知所属channelpipeline中的下一个handler,也可动态修改其所属的channelpipeline,具体功能如下: 通知.通过调用channelhandlercontext提供的方法可以调用同一个channelpipeline中的相邻的下一个channelhandler,详情可以参照chann

netty io.netty.channel 简介1

Interface AddressedEnvelope<M,A extends SocketAddress> 此接口将一个消息.发送地址和接收地址封装到了一起 Interface Channel 此接口表示到网络socket或者组件(component)的一个连接,其提供了IO操作的一些功能,比如read, write, connect, and bind.一个channel可以给用户提供如下功能:1.当前channel的状态(open.connected等).2.channel的配置参数(如

填坑netty io.netty.util.internal.OutOfDirectMemoryError

我们有个与外部交互的接口是采用netty http,具体版本netty-4.1.18,为什么使用这个版本,我也不知道,历史原因. 由于netty都是异步请求,所以与外部交互总有些唯一的业务标识需要保存,以便前后数据可以勾兑. 这里先说明下,netty里的ByteBuf在读取channelRead未进行写write操作时,需要自己释放release.这和本次Error关系不大,继续说重点. 查看日志,首先发现了OutOfDirectMemoryError错误,这个错误也是间断性的出现,显然是内存不

Java io.netty.util.ReferenceCountUtil 代码实例

原文:https://www.helplib.com/Java_API_Classes/article_64580 以下是展示如何使用io.netty.util.ReferenceCountUtil的最佳示例. 我们使用了代码质量辨别算法从开源项目中提取出了最佳的优秀示例. 实例 1 复制代码 private static void testPerformOpeningHandshake0(boolean subProtocol) { EmbeddedChannel ch = new Embed

Netty对Protocol Buffer多协议的支持(八)

Netty对Protocol Buffer多协议的支持(八) 一.背景 在上篇博文中笔者已经用代码演示了如何在netty中使用Protocol Buffer,然而细心的用户可能会发现一个明显的不足之处就是,我们的Handler只能处理一种特定的类型,而我们的项目中又不可能只有一种类型,那么这个问题该怎么解决了?多的不说,笔者直接上代码. 二.代码实现 2.1 message的编写 syntax = "proto2"; package com.rsy.netty.protobuf; op

【转】Netty那点事(二)Netty中的buffer

[原文]https://github.com/code4craft/netty-learning/blob/master/posts/ch2-buffer.md 上一篇文章我们概要介绍了Netty的原理及结构,下面几篇文章我们开始对Netty的各个模块进行比较详细的分析.Netty的结构最底层是buffer机制,这部分也相对独立,我们就先从buffer讲起. What:buffer二三事 buffer中文名又叫缓冲区,按照维基百科的解释,是"在数据传输时,在内存里开辟的一块临时保存数据的区域&q

io.netty.resolver.dns.DnsNameResolverContext

java.net.UnknownHostException: failed to resolve 'xxx.com' after 3 queries at io.netty.resolver.dns.DnsNameResolverContext.finishResolve(DnsNameResolverContext.java:699) at io.netty.resolver.dns.DnsNameResolverContext.tryToFinishResolve(DnsNameResolv

记一次netty版本冲突,报java.lang.NoSuchMethodError: io.netty.util.internal.ObjectUtil.checkPositive的问题

elasticsearch 5.6中使用TransportClient初始化抛异常 在引入elasticsearch5.6的transportclient包中,会引入netty进行通信. <!-- transport客户端 --> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>transport</artifactId> <version

netty报错:io.netty.channel.ChannelPipelineException

1.九月 23, 2018 8:35:02 下午 io.netty.channel.ChannelInitializer channelRegistered警告: Failed to initialize a channel. Closing: [id: 0xa09c718b, /127.0.0.1:50509 => /127.0.0.1:9999]io.netty.channel.ChannelPipelineException: com.sxt.netty.first.Server4Hell