运营 网站,建设生鲜网站价格表,如何在jsp上做网站页面代码,设计工作室效果图了解 Netty 中的 ByteBuf 类吗#xff1f;
答#xff1a;
在 Java NIO 编程中#xff0c;Java 提供了 ByteBuffer 作为字节缓冲区类型#xff08;缓冲区可以理解为一段内存区域#xff09;#xff0c;来表示一个连续的字节序列。
Netty 中并没有使用 Java 的 ByteBuff…了解 Netty 中的 ByteBuf 类吗
答
在 Java NIO 编程中Java 提供了 ByteBuffer 作为字节缓冲区类型缓冲区可以理解为一段内存区域来表示一个连续的字节序列。
Netty 中并没有使用 Java 的 ByteBuffer而是使用了新的缓冲类型 ByteBuf特性如下 允许自定义缓冲类型 复合缓冲类型中内置的透明的零拷贝实现 开箱即用的动态缓冲类型具有像 StringBuffer 一样的动态缓冲能力 不再需要调用 flip() 方法 Java 的 ByteBuffer 类中需要使用 flip() 来进行读写两种模式的切换 正常情况下具有比 ByteBuffer 更快的响应速度
Java 中的 ByteBuffer
主要需要注意有 3 个属性position、limit、capacity
capacity当前数组的容量大小position写入模式的可写入数据的下标读取模式的可读取数据下标limit写入模式的可写入数组大小读取模式的最多可以读取数据的下标
假如说数组容量是 10那么三个值初始值为
position 0
limit 10
capacity 10假如写入 4 个字节的数据此时三个值如下
position 4
limit 10
capacity 10如果切换到读取数据模式使用 flip()会改变上边的三个值会从 position 的位置开始读取数据到 limit 的位置
position 0
limit 4
capacity 10Netty 中的 ByteBuf
ByteBuf 主要使用两个指针来完成缓冲区的读写操作分别是 readIndex 和 writeIndex
当写入数据时writeIndex 会增加当读取数据时readIndex 会增加但不会超过 writeIndex
ByteBuf 的使用
public static void main(String[] args) {ByteBuf buffer Unpooled.buffer(10);System.out.println(----------初始化ByteBuf----------);printByteBuffer(buffer);System.out.println(----------ByteBuf写入数据----------);String str hello world!;buffer.writeBytes(str.getBytes());printByteBuffer(buffer);System.out.println(----------ByteBuf读取数据----------);while (buffer.isReadable()) {System.out.print((char)buffer.readByte());}System.out.println();printByteBuffer(buffer);System.out.println(----------ByteBuf释放无用空间----------);buffer.discardReadBytes();printByteBuffer(buffer);System.out.println(----------ByteBuf清空----------);buffer.clear();printByteBuffer(buffer);
}
private static void printByteBuffer(ByteBuf buffer) {System.out.println(readerIndex: buffer.readerIndex());System.out.println(writerIndex: buffer.writerIndex());System.out.println(capacity: buffer.capacity());
}
/**输出**/
----------初始化ByteBuf----------
readerIndex:0
writerIndex:0
capacity:10
----------ByteBuf写入数据----------
readerIndex:0
writerIndex:12
capacity:64
----------ByteBuf读取数据----------
hello world!
readerIndex:12
writerIndex:12
capacity:64
----------ByteBuf释放无用空间----------
readerIndex:0
writerIndex:0
capacity:64
----------ByteBuf清空----------
readerIndex:0
writerIndex:0
capacity:64ByteBuf 的 3 种使用模式
ByteBuf 共有 3 种使用模式 堆缓冲区模式Heap Buffer 堆缓冲区模式又称为 “支撑数据”其数据存放在 JVM 的堆空间 优点 数据在 JVM 堆中存储可以快速创建和释放并且提供了数组直接快速访问的方法 缺点 每次数据与 IO 进行传输时都需要将数据复制到直接缓冲区这里为什么要将数据复制到直接缓冲区的原因在上边的 直接内存比堆内存快在了哪里 问题中已经讲过 创建代码 ByteBuf buffer Unpooled.buffer(10);直接缓冲区模式Direct Buffer 直接缓冲区模式属于堆外分配的直接内存不占用堆的容量 优点 使用 socket 传输数据时性能很好避免了数据从 JVM 堆内存复制到直接缓冲区 缺点 相比于堆缓冲区直接缓冲区分配内存空间和释放更为昂贵 创建代码 ByteBuf buffer Unpooled.directBuffer(10);复合缓冲区模式Composite Buffer 本质上类似于提供一个或多个 ByteBuf 的组合视图 优点 提供一种方式让使用者自由组合多个 ByteBuf避免了复制和分配新的缓冲区 缺点 不支持访问其支撑数据如果要访问需要先将内容复制到堆内存再进行访问 创建代码 public static void main(String[] args) {
// AnnotationConfigApplicationContext context new AnnotationConfigApplicationContext(Test.class);// 创建一个堆缓冲区ByteBuf heapBuf Unpooled.buffer(2);String str1 hi;heapBuf.writeBytes(str1.getBytes());// 创建一个直接缓冲区ByteBuf directBuf Unpooled.directBuffer(5);String str2 nihao;directBuf.writeBytes(str2.getBytes());// 创建一个复合缓冲区CompositeByteBuf compositeByteBuf Unpooled.compositeBuffer(10);compositeByteBuf.addComponents(heapBuf, directBuf);// 检查是否支持支撑数组发现并不支持if (!compositeByteBuf.hasArray()) {for (ByteBuf buf : compositeByteBuf) {// 第一个字节偏移量int offset buf.readerIndex();// 总共数据长度int length buf.readableBytes();byte[] bytes new byte[length];// 不支持访问支撑数组需要将内容复制到堆内存中即 bytes 数组中才可以进行访问buf.getBytes(offset, bytes);printByteBuffer(bytes, offset, length);}}
}private static void printByteBuffer(byte[] array, int offset, int length) {System.out.println(array: array);System.out.println(array-String: new String(array));System.out.println(offset: offset);System.out.println(len: length);
}
/**输出**/
array:[B4f8e5cde
array-String:hi
offset:0
len:2
array:[B504bae78
array-String:nihao
offset:0
len:5
Netty 中 ByteBuf 如何分配有池化的操作吗
答
ByteBuf 的分配接口定义在了 ByteBufAllocator 中他的直接抽象类是 AbstractByteBufAllocator而 AbstractByteBufAllocator 有两种实现PooledByteBufAllocator 和 UnpooledByteBufAllocator PooledByteBufAllocator 提供了池化的操作将 ByteBuf 实例放入池中提升了性能将内存碎片化减到了最小UnpooledByteBufAllocator。这个实现采用了一种内存分配的高效策略成为 jemalloc已经被好几种现代操作系统所采用UnpooledByteBufAllocator 在每次创建缓冲区时都会返回一个新的 ByteBuf 实例这些实例由 JVM 负责 gc 回收