netty 分布式,netty bytebuffer

  netty 分布式,netty bytebuffer

  

目录

ByteBuf根据不同的分类方法会有不同的分类结果。1.汇集和未汇集2。2.基于直接内存的Bytebuf和基于堆内存的Bytebuf。3.安全与不安全抽象类AbstractByteBuf在上一节已经简单介绍过了,本节也简单介绍了它的子类的分类。

 

  00-1010我们先来看第一个分类。

  

ByteBuf根据不同的分类方式 会有不同的分类结果

pooled就是从一块内存中取出一个连续的内存,打包成byteBuf。

 

  标志是类名以Pooled开头的ByteBuf,通常是Pooled类型的ByteBuf,比如: PooledDirectByteBuf或者pooledHeapByteBuf。

  我们将在接下来的章节中讨论如何分配连续内存。

  Unpooled是在分配时直接调用系统api实现的,具体的符号是以un pooled开头的ByteBuf,比如unpoooleddirectbytebuf,unpoooledheepbytebuf。

  再看第二个分类。

  00-1010 ByteBuf基于直接内存。具体的符号是ByteBuf,其类名包含direct这个词,如unprolleddirectbyteBUF、pooleddirectbyteBUF等。

  ByteBuf基于堆内存,具体标志是类名中带有heap一词的ByteBuf,如unpaoledheapbytebuf和pooledheepbytebuf。

  结合以上两种方式,这里简单分析一下其按创作方式的分类。

  这里的第一种分类池是分配一个连续的内存来创建byteBuf。这一节将在下一节讨论,不举例。

  这里主要看Unpooled,也就是通过调用系统api来创建byteBuf。直接内存和堆内存有什么区别?

  这里以UnpooledDirectByteBuf和UnpooledHeapByteBuf两个例子,简单介绍一下它的创建方法3360。

  首先看UnpooledHeapByteBuf的byetBuf,它基于内存创建ByteBuf,直接调用系统api。

  再来看UnpooledHeapByteBuf的byetBuf的构造方法:

  protected unpooledheapbytebuff(bytefallocator alloc,int initialCapacity,int maxCapacity) { this(alloc,new byte[initialCapacity],0,0,max capacity);}这里调用自己的构造方法,在参数中创建新的字节数组,初始长度为初始化的内存大小,读写指针的初始位置都为0,传入最大内存大小。

  从这里我们可以看到,非池型堆内存的分配是通过字节数组实现的。

  下到:

  protected unpoedheapbytebuf(bytefallocator alloc,byte[] initialArray,int maxCapacity) { this(alloc,initialArray,0,initialArray.length,max capacity);}继续关注:

  private unpoedheapbytebuf(bytefallocator alloc,byte[] initialArray,int readerIndex,int writerIndex,int max capacity){ super(max capacity);//忽略验证码this.alloc=allocset array(initial array);setIndex(readerIndex,writer index);}到setAarry方法:

  private void set array(byte[]initial array){ array=initial array;tmpNioBuf=null}将新创建的数组赋给自己的array属性。

  回到构造函数中,遵循setIndex方法3360。

  public byte buf setIndex(int reader index,int

   writerIndex) { //忽略验证代码 setIndex0(readerIndex, writerIndex); return this;}这里实际上是调用了AbstractByteBuf的setIndex方法

  我们跟进setIndex0方法中:

  

final void setIndex0(int readerIndex, int writerIndex) { this.readerIndex = readerIndex; this.writerIndex = writerIndex;}

这里设置了读写指针, 根据之前的调用链我们知道, 这里将读写指针位置都设置为了0

 

  介绍完UnpooledHeapByteBuf的初始化, 我们继续看UnpooledDirectByteBuf这个类的构造, 顾明思议, 是基于堆外内存, 并且同样也是调用系统api的方式进行实现的

  我们看其构造方法:

  

protected UnpooledDirectByteBuf(ByteBufAllocator alloc, int initialCapacity, int maxCapacity) { super(maxCapacity); //忽略验证代码 this.alloc = alloc; setByteBuffer(ByteBuffer.allocateDirect(initialCapacity));}

我们关注下setByteBuffer中的参数ByteBuffer.allocateDirect(initialCapacity)

 

  我们在这里看到, 这里通过jdk的ByteBuffer直接调用静态方法allocateDirect分配了一个基于直接内存的ByteBuffer, 并设置了初始内存

  再跟到setByteBuffer方法中:

  

private void setByteBuffer(ByteBuffer buffer) { ByteBuffer oldBuffer = this.buffer; if (oldBuffer != null) { //代码忽略 } this.buffer = buffer; tmpNioBuf = null; capacity = buffer.remaining();}

我们看到在这里将分配的ByteBuf设置到当前类的成员变量中

 

  以上两种实例, 我们会对上面所讲到的两种分类有个初步的了解

  这里要注意一下, 基于堆内存创建ByteBuf, 可以不用考虑对象回收, 因为虚拟机会进行垃圾回收, 但是堆外内存在虚拟机的垃圾回收机制的作用域之外, 所以这里要考虑手动回收对象

  最后, 我们看第三种分类方式:

  

 

  

3.safe和unsafe

首先从名字上看, safe代表安全的, unsafe代表不安全的

 

  这个安全与不安全的定义是什么呢

  其实在我们jdk里面有unsafe对象, 可以通过unsafe对象直接拿到内存地址, 基于内存地址可以进行读写操作

  如果是Usafe类型的byteBuf, 则可以直接拿到byteBuf在jvm中的具体内存, 可以通过调用jdk的Usafe对象进行读写, 所以这里代表不安全

  而非Usafe不能拿到jvm的具体内存, 所以这里代表安全

  具体标志是如果类名中包含unsafe这个单词的ByteBuf, 可以认为是一个unsafe类型的ByteBuf, 比如PooledUnsafeHeapByteBuf或者PooledUnsafeDirectByteBuf

  以PooledUnsafeHeapByteBuf的_getByte方法为例:

  

protected byte _getByte(int index) { return UnsafeByteBufUtil.getByte(memory, idx(index));}

这里memory代表byebuffer底层分配内存的首地址, idx(index)代表当前指针index距内存memory的偏移地址, UnsafeByteBufUtil的getByte方法, 就可以直接通过这两个信息通过jdk底层的unsafe对象拿到jdk底层的值

 

  有关AbstractByteBuf的主要实现类和继承关系, 如下图所示:

  

 

  以上就是Netty分布式ByteBuf的分类方式源码解析的详细内容,更多关于Netty分布式ByteBuf分类方式的资料请关注盛行IT其它相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: