[netty核心类]--缓冲区ByteBuf

2024-05-23 18:38
文章标签 核心 netty 缓冲区 bytebuf

本文主要是介绍[netty核心类]--缓冲区ByteBuf,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文主要包括以下内容:
1)ByteBuf的三种类型:heapBuffer(堆缓冲区)、directBuffer(直接缓冲区)以及Composite Buffer(复合缓冲区)。

2)ByteBuf的工作原理。

3)ByteBuf与JDK中ByteBuffer的区别以及对比

4)ByteBuf的引用计数器实现类AbstractReferenceCountedByteBuf分析。

5)UnpooledHeapByteBuf 基于堆内存缓冲器的源码分析

6)PooledDirectByteBuf 源码分析

1. netty中ByteBuf的优势

缓冲区是不同的通道之间传递数据的中介,JDK中的ByteBuffer操作复杂,而且没有经过优化,所以在netty中实现了一个更加强大的缓冲区 ByteBuf 用于表示字节序列。ByteBuf在netty中是通过Channel传输数据的,新的设计解决了JDK中ByteBuffer中的一些问题。

netty中ByteBuf的缓冲区的优势:
(1)可以自定义缓冲区的类型;

(2)通过内置的复合缓冲类型实现零拷贝;

(3)不需要调用flip()函数切换读/写模式

(4)读取和写入的索引分开了,不像JDK中使用一个索引

(5)引用计数(referenceCounting的实现原理?)

(6) Pooling池

2.netty中的ByteBuf的类型:

JDK中的Buffer的类型 有heapBuffer和directBuffer两种类型,但是在netty中除了heap和direct类型外,还有composite Buffer(复合缓冲区类型)。

(1)Heap Buffer 堆缓冲区

这是最常用的类型,ByteBuf将数据存储在JVM的堆空间,通过将数据存储在数组中实现的。
1)堆缓冲的优点是:由于数据存储在JVM的堆中可以快速创建和快速释放,并且提供了数组的直接快速访问的方法。

2)堆缓冲缺点是:每次读写数据都要先将数据拷贝到直接缓冲区再进行传递。

(2)Direct Buffer 直接缓冲区

Direct Buffer在堆之外直接分配内存,直接缓冲区不会占用堆的容量。

(1)Direct Buffer的优点是:在使用Socket传递数据时性能很好,由于数据直接在内存中,不存在从JVM拷贝数据到直接缓冲区的过程,性能好。

(2)缺点是:因为Direct Buffer是直接在内存中,所以分配内存空间和释放内存比堆缓冲区更复杂和慢。

虽然netty的Direct Buffer有这个缺点,但是netty通过内存池来解决这个问题。直接缓冲池不支持数组访问数据,但可以通过间接的方式访问数据数组:

ByteBuf directBuf = Unpooled.directBuffer(16);   
if(!directBuf.hasArray()){   int len = directBuf.readableBytes();   byte[] arr = new byte[len];   directBuf.getBytes(0, arr);   
}  

但是上面的操作太过复杂,所以在使用时,建议一般是用heap buffer。

不过对于一些IO通信线程中读写缓冲时建议使用DirectByteBuffer,因为这涉及到大量的IO数据读写。对于后端的业务消息的编解码模块使用HeapByteBuffer。

(3)Composite Buffer 复合缓冲区

这个是netty特有的缓冲类型。复合缓冲区就类似于一个ByteBuf的组合视图,在这个视图里面我们可以创建不同的ByteBuf(可以是不同类型的)。 这样,复合缓冲区就类似于一个列表,我们可以动态的往里面添加和删除其中的ByteBuf,JDK里面的ByteBuffer就没有这样的功能。

Netty提供了Composite ByteBuf来处理复合缓冲区。例如:一条消息由Header和Body组成,将header和body组装成一条消息发送出去。下图显示了Composite ByteBuf组成header和body:
这里写图片描述

如果使用的是JDK的ByteBuffer就不能简单的实现,只能通过创建数组或则新的ByteBuffer,再将里面的内容复制到新的ByteBuffer中,下面给出了一个CompositeByteBuf的使用示例:

//组合缓冲区
CompositeByteBuf compBuf = Unpooled.compositeBuffer();   
//堆缓冲区
ByteBuf heapBuf = Unpooled.buffer(8);   
//直接缓冲区
ByteBuf directBuf = Unpooled.directBuffer(16);   
//添加ByteBuf到CompositeByteBuf   
compBuf.addComponents(heapBuf, directBuf);   
//删除第一个ByteBuf   
compBuf.removeComponent(0);   
Iterator<ByteBuf> iter = compBuf.iterator();   
while(iter.hasNext()){   System.out.println(iter.next().toString());   
}   //使用数组访问数据      
if(!compBuf.hasArray()){   int len = compBuf.readableBytes();   byte[] arr = new byte[len];   compBuf.getBytes(0, arr);   
}   

这篇关于[netty核心类]--缓冲区ByteBuf的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/996362

相关文章

详解MySQL中DISTINCT去重的核心注意事项

《详解MySQL中DISTINCT去重的核心注意事项》为了实现查询不重复的数据,MySQL提供了DISTINCT关键字,它的主要作用就是对数据表中一个或多个字段重复的数据进行过滤,只返回其中的一条数据... 目录DISTINCT 六大注意事项1. 作用范围:所有 SELECT 字段2. NULL 值的特殊处

Python包管理工具核心指令uvx举例详细解析

《Python包管理工具核心指令uvx举例详细解析》:本文主要介绍Python包管理工具核心指令uvx的相关资料,uvx是uv工具链中用于临时运行Python命令行工具的高效执行器,依托Rust实... 目录一、uvx 的定位与核心功能二、uvx 的典型应用场景三、uvx 与传统工具对比四、uvx 的技术实

Go语言中泄漏缓冲区的问题解决

《Go语言中泄漏缓冲区的问题解决》缓冲区是一种常见的数据结构,常被用于在不同的并发单元之间传递数据,然而,若缓冲区使用不当,就可能引发泄漏缓冲区问题,本文就来介绍一下问题的解决,感兴趣的可以了解一下... 目录引言泄漏缓冲区的基本概念代码示例:泄漏缓冲区的产生项目场景:Web 服务器中的请求缓冲场景描述代码

java中Optional的核心用法和最佳实践

《java中Optional的核心用法和最佳实践》Java8中Optional用于处理可能为null的值,减少空指针异常,:本文主要介绍java中Optional核心用法和最佳实践的相关资料,文中... 目录前言1. 创建 Optional 对象1.1 常规创建方式2. 访问 Optional 中的值2.1

Java Jackson核心注解使用详解

《JavaJackson核心注解使用详解》:本文主要介绍JavaJackson核心注解的使用,​​Jackson核心注解​​用于控制Java对象与JSON之间的序列化、反序列化行为,简化字段映射... 目录前言一、@jsonProperty-指定JSON字段名二、@JsonIgnore-忽略字段三、@Jso

Python列表去重的4种核心方法与实战指南详解

《Python列表去重的4种核心方法与实战指南详解》在Python开发中,处理列表数据时经常需要去除重复元素,本文将详细介绍4种最实用的列表去重方法,有需要的小伙伴可以根据自己的需要进行选择... 目录方法1:集合(set)去重法(最快速)方法2:顺序遍历法(保持顺序)方法3:副本删除法(原地修改)方法4:

SpringQuartz定时任务核心组件JobDetail与Trigger配置

《SpringQuartz定时任务核心组件JobDetail与Trigger配置》Spring框架与Quartz调度器的集成提供了强大而灵活的定时任务解决方案,本文主要介绍了SpringQuartz定... 目录引言一、Spring Quartz基础架构1.1 核心组件概述1.2 Spring集成优势二、J

Pyserial设置缓冲区大小失败的问题解决

《Pyserial设置缓冲区大小失败的问题解决》本文主要介绍了Pyserial设置缓冲区大小失败的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录问题描述原因分析解决方案问题描述使用set_buffer_size()设置缓冲区大小后,buf

Java的IO模型、Netty原理解析

《Java的IO模型、Netty原理解析》Java的I/O是以流的方式进行数据输入输出的,Java的类库涉及很多领域的IO内容:标准的输入输出,文件的操作、网络上的数据传输流、字符串流、对象流等,这篇... 目录1.什么是IO2.同步与异步、阻塞与非阻塞3.三种IO模型BIO(blocking I/O)NI

Python循环缓冲区的应用详解

《Python循环缓冲区的应用详解》循环缓冲区是一个线性缓冲区,逻辑上被视为一个循环的结构,本文主要为大家介绍了Python中循环缓冲区的相关应用,有兴趣的小伙伴可以了解一下... 目录什么是循环缓冲区循环缓冲区的结构python中的循环缓冲区实现运行循环缓冲区循环缓冲区的优势应用案例Python中的实现库