• Netty ByteBuf


    一、功能原理
     
    ByteBuf是一个byte存放的缓冲区。
     
    ByteBuf通过两个位置的指针来协助缓冲区的读写操作,读操作使用readIndex,写操作使用writeIndex。
    +-------------------+------------------+------------------+
    | discardable bytes |  readable bytes  |  writable bytes  |
    |                   |     (CONTENT)    |                  |
    +-------------------+------------------+------------------+
    |                   |                  |                  |
    0      <=      readerIndex   <=   writerIndex    <=    capacity
    discardable bytes 丢弃的读空间
    readable bytes 可读空间
    writeable bytes 可写空间
     
    比如:
    [java] view plain copy
     
     
    1. ByteBuf heapBuffer = Unpooled.buffer();  
    2. System.out.println(heapBuffer);  
    1.  
      ByteBuf heapBuffer = Unpooled.buffer();
    2.  
      System.out.println(heapBuffer);
    结果:
    [java] view plain copy
     
     
    1. UnpooledHeapByteBuf(ridx: 0, widx: 0, cap: 256)  
    UnpooledHeapByteBuf(ridx: 0, widx: 0, cap: 256)
    ridx是readerIndex读取数据索引,位置从0开始
    widx是writeIndex写数据索引,位置从0开始
    cap是capacity缓冲区初始化的容量,默认256,可以通过Unpooled.buffer(8)设置,初始化缓冲区容量是8。
     
    如果写入内容超过cap,cap会自动增加容量,但不能超过缓冲区最大容量maxCapacity。
    [java] view plain copy
     
     
    1. ByteBuf heapBuffer = Unpooled.buffer(8);  
    2. System.out.println("初始化:"+heapBuffer);  
    3. heapBuffer.writeBytes("测试测试测试");  
    4. System.out.println("写入测试测试测试:"+heapBuffer);  
    1.  
      ByteBuf heapBuffer = Unpooled.buffer(8);
    2.  
      System.out.println("初始化:"+heapBuffer);
    3.  
      heapBuffer.writeBytes("测试测试测试");
    4.  
      System.out.println("写入测试测试测试:"+heapBuffer);
    结果:
    [java] view plain copy
     
     
    1. 初始化:UnpooledHeapByteBuf(ridx: 0, widx: 0, cap: 8)  
    2. 写入测试测试测试:UnpooledHeapByteBuf(ridx: 0, widx: 18, cap: 64)  
    1.  
      初始化:UnpooledHeapByteBuf(ridx: 0, widx: 0, cap: 8)
    2.  
      写入测试测试测试:UnpooledHeapByteBuf(ridx: 0, widx: 18, cap: 64)
    cap初始化8,增加到64
     
    缓冲内容复制到字节数组
    [java] view plain copy
     
     
    1. //1、创建缓冲区  
    2. ByteBuf heapBuffer = Unpooled.buffer(8);  
    3.           
    4. //2、写入缓冲区内容  
    5. heapBuffer.writeBytes("测试测试测试".getBytes());  
    6.           
    7. //3、创建字节数组  
    8. byte[] b = new byte[heapBuffer.readableBytes()];  
    9.           
    10. System.out.println(b[11]);  
    11.           
    12. //4、复制内容到字节数组b  
    13. heapBuffer.readBytes(b);  
    14.           
    15. System.out.println(b[11]);  
    16.           
    17. //5、字节数组转字符串  
    18. String str = new String(b);  
    19.           
    20. System.out.println(str);  
    1.  
      //1、创建缓冲区
    2.  
      ByteBuf heapBuffer = Unpooled.buffer(8);
    3.  
       
    4.  
      //2、写入缓冲区内容
    5.  
      heapBuffer.writeBytes("测试测试测试".getBytes());
    6.  
       
    7.  
      //3、创建字节数组
    8.  
      byte[] b = new byte[heapBuffer.readableBytes()];
    9.  
       
    10.  
      System.out.println(b[11]);
    11.  
       
    12.  
      //4、复制内容到字节数组b
    13.  
      heapBuffer.readBytes(b);
    14.  
       
    15.  
      System.out.println(b[11]);
    16.  
       
    17.  
      //5、字节数组转字符串
    18.  
      String str = new String(b);
    19.  
       
    20.  
      System.out.println(str);
    结果:
    [java] view plain copy
     
     
    1. 0  
    2. -107  
    3. 测试测试测试  
    1.  
      0
    2.  
      -107
    3.  
      测试测试测试

    ByteBuf转ByteBuffer
    [java] view plain copy
     
     
    1. ByteBuffer bb = heapBuffer.nioBuffer();  
    ByteBuffer bb = heapBuffer.nioBuffer();

    ByteBuf的主要类继承关系图
     
    从内存分配的角度看,ByteBuf可以分为两类:
     
    1、堆内存(HeapByteBuf)字节缓冲区:特点是内存的分配和回收速度快,可以被JVM自动回收;缺点就是如果进行Socket的IO读写,需要额外做一次内存复制,将堆内存对应的缓冲区复制到内核Channel中,性能会有一定程度的下降
     
    2、直接内存(DirectByteBuf) 字节缓冲区:非堆内存,它在对外进行内存分配,相比于堆内存,它的分配和回收速度会慢一些,但是将它写入或者从Socket Channel中读取时,由于少一次内存复制,速度比堆内存快
     
    Netty的最佳实践是在I/O通信线程的读写缓冲区使用DirectByteBuf,后端业务消息的编解码模块使用HeapByteBuf,这样组合可以达到性能最优。
     
    ByteBuf的四种声明方式
    [java] view plain copy
     
     
    1. ByteBuf heapBuffer = Unpooled.buffer();  
    2. System.out.println(heapBuffer);  
    3.           
    4. ByteBuf directBuffer = Unpooled.directBuffer();  
    5. System.out.println(directBuffer);  
    6.           
    7. ByteBuf wrappedBuffer = Unpooled.wrappedBuffer(new byte[128]);  
    8. System.out.println(wrappedBuffer);  
    9.           
    10. ByteBuf copiedBuffer = Unpooled.copiedBuffer(new byte[128]);  
    11. System.out.println(copiedBuffer);  
    1.  
      ByteBuf heapBuffer = Unpooled.buffer();
    2.  
      System.out.println(heapBuffer);
    3.  
       
    4.  
      ByteBuf directBuffer = Unpooled.directBuffer();
    5.  
      System.out.println(directBuffer);
    6.  
       
    7.  
      ByteBuf wrappedBuffer = Unpooled.wrappedBuffer(new byte[128]);
    8.  
      System.out.println(wrappedBuffer);
    9.  
       
    10.  
      ByteBuf copiedBuffer = Unpooled.copiedBuffer(new byte[128]);
    11.  
      System.out.println(copiedBuffer);
    结果:
    [java] view plain copy
     
     
    1. UnpooledHeapByteBuf(ridx: 0, widx: 0, cap: 256)  
    2. SimpleLeakAwareByteBuf(UnpooledUnsafeDirectByteBuf(ridx: 0, widx: 0, cap: 256))  
    3. UnpooledHeapByteBuf(ridx: 0, widx: 128, cap: 128/128)  
    4. UnpooledHeapByteBuf(ridx: 0, widx: 128, cap: 128/128)  
  • 相关阅读:
    jacman主题分页出现问题(Next<span></span>)
    后会有期(非技术)
    再谈前端性能优化
    emmet常用指令组合
    imagemagick在windows下安装(转,有改动)
    nth-child和蝉原则实现的奇妙随机效果(译)
    flex布局浅谈和实例
    css命名那些事儿
    chrome开发者工具浅析--timeline
    浏览器历史和发展趋势浅析
  • 原文地址:https://www.cnblogs.com/endv/p/14238904.html
Copyright © 2020-2023  润新知