Netty Review - 探索ByteBuf的内部机制

文章目录

  • 概念
  • ByteBuf VS Java NIO Buffer
  • ByteBuf实现类
    • HeapByteBuf vs DirectByteBuf
    • PooledByteBuf vs UnpooledByteBuf
    • 其他
  • ByteBuf的实现机制

在这里插入图片描述


概念

ByteBuf是Netty中用于处理二进制数据的缓冲区

Netty的ByteBuf是一个可用于高效存储和操作字节数据的数据结构。与传统的ByteBuffer相比,ByteBuf提供了更灵活、更强大的API。

主要特性:

  • 可扩展性: ByteBuf支持动态扩展,可以自动扩展其容量以适应数据的增长。

  • 读写索引分离: 与ByteBuffer不同,ByteBuf有独立的读和写索引。这意味着可以读取和写入数据而无需手动切换模式。

  • 零拷贝: ByteBuf支持零拷贝操作,可以提高性能并降低内存复制的开销。

  • 池化支持: Netty提供了ByteBuf的池化支持,可帮助有效地重用内存以减少垃圾收集的压力。


ByteBuf VS Java NIO Buffer

ByteBuf则是Java NIO Buffer的新轮子,官方列出了一些ByteBuf的特性:

  • 需要的话,可以自定义buffer类型;
  • 通过组合buffer类型,可实现透明的zero-copy;
  • 提供动态的buffer类型,如StringBuffer一样,容量是按需扩展;
  • 无需调用flip()方法

ByteBuf实现类

ByteBuf提供了一些较为丰富的实现类,逻辑上主要分为两种:

  • HeapByteBuf
  • DirectByteBuf

实现机制则分为两种:

  • PooledByteBuf
  • UnpooledByteBuf

除了这些之外,Netty还实现了一些衍生ByteBuf(DerivedByteBuf),如:ReadOnlyByteBufDuplicatedByteBuf以及SlicedByteBuf

在这里插入图片描述

HeapByteBuf vs DirectByteBuf

HeapByteBufDirectByteBuf区别在于Buffer的管理方式:

  • HeapByteBuf由Heap管理,Heap是Java堆的意思,内部实现直接采用byte[] array;
  • DirectByteBuf使用是堆外内存,Direct应是采用Direct I/O之意,内部实现使用java.nio.DirectByteBuffer

PooledByteBuf vs UnpooledByteBuf

  • UnpooledByteBuf实现就是普通的ByteBuf了
  • PooledByteBuf是4.x之后的新特性

其他

  • DerivedByteBuf是ByteBuf衍生类,实现采用装饰器模式对原有的ByteBuf进行了一些封装。
  • ReadOnlyByteBuf是某个ByteBuf的只读引用;
  • DuplicatedByteBuf是某个ByteBuf对象的引用;
  • SlicedByteBuf是某个ByteBuf的部分内容。

ByteBuf的实现机制

Netty中的ByteBuf是一个强大的字节容器,用于处理字节数据。它的实现机制相当复杂,其主要特点如下

  • 内存分配: Netty的ByteBuf使用了一种称为池化的内存管理机制。这意味着它不是每次都直接分配新的内存,而是从预分配的内存池中获取。这有助于减少内存碎片化和提高性能。

    4.x开发了Pooled Buffer,实现了一个高性能的buffer池,分配策略则是结合了buddy allocation和slab allocation的jemalloc变种,代码在io.netty.buffer.PoolArena

  • 引用计数: ByteBuf使用了引用计数机制来跟踪对它的引用。这种方式允许多个部分同时引用同一个ByteBuf,而不会导致内存泄漏。当引用计数降至零时,内存将被释放回池。

  • 可读写的索引: ByteBuf通过维护两个索引来实现读写操作,分别是读索引(readerIndex)和写索引(writerIndex)。这两个索引允许你从中读取数据或将数据写入,而不会相互影响。

  • 零拷贝: Netty的ByteBuf支持零拷贝的特性,这意味着在某些情况下,数据可以在不涉及实际数据复制的情况下传递给其他组件。这对于提高性能和降低资源消耗非常重要。

    Zero-copy与传统意义的zero-copy不太一样。传统的zero-copy是IO传输过程中,数据无需中内核态到用户态、用户态到内核态的数据拷贝,减少拷贝次数。而Netty的zero-copy则是完全在用户态,或者说传输层的zero-copy机制,如下图。

    由于协议传输过程中,通常会有拆包、合并包的过程,一般的做法就是System.arrayCopy了,但是Netty通过ByteBuf.slice以及Unpooled.wrappedBuffer等方法拆分、合并Buffer无需拷贝数据。

    如何实现zero-copy的呢。slice实现就是创建一个SlicedByteBuf对象,将this对象,以及相应的数据指针传入即可,wrappedBuffer实现机制类似

    在这里插入图片描述

  • Composite ByteBuf: Netty提供了CompositeByteBuf,它是一种特殊的ByteBuf,可以将多个ByteBuf组合成一个逻辑上的ByteBuf。这使得可以在不实际复制数据的情况下聚合多个缓冲区

ByteBuf buffer1 = Unpooled.copiedBuffer("Hello, ".getBytes());
ByteBuf buffer2 = Unpooled.copiedBuffer("Netty!".getBytes());CompositeByteBuf compositeBuffer = allocator.compositeBuffer();
compositeBuffer.addComponent(true, buffer1);
compositeBuffer.addComponent(true, buffer2);// 使用compositeBuffer进行操作,它看起来像一个大的ByteBuf

CompositeByteBuf可以将多个ByteBuf组合成一个逻辑上的ByteBuf。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/213082.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(保姆级教程)Mysql中索引、触发器、存储过程、存储函数的概念、作用,以及如何使用索引、存储过程,代码操作演示

讲解 MySQL 中索引、触发器、存储过程、存储函数的使用 文章目录 1. 索引1.1 索引的分类1.2 索引的设计原则1.3 如何使用(create index) 2. 触发器2.1 触发器的分类2.2 如何使用(create trigger) 3. 存储过程3.1 如何使用&#xf…

计算机网络——物理层相关习题(计算机专业考研全国统考历年真题)

目录 2012-34 原题 答案 解析 2018-34 原题 答案 解析 2009/2011-34 原题 答案 解析 2016-34 原题 答案 解析 2014-35/2017-34 原题 答案 解析 2013-34 原题 答案 解析 2015-34 原题 答案 解析 物理层的协议众多,这是因为物理层…

在数组的指定位置插入指定元素值numpy.insert()

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 在数组的指定位置插入指定元素值 numpy.insert() [太阳]选择题 请问以下代码中最后输出结果是? import numpy as np arr np.array([1, 2, 3]) print("【显示】arr ",…

微信小程序使用腾讯地图实现地点搜索并且随着地图的滑动加载滑动到区域的地点,本文地点使用医院关键词作为搜索地点

实现效果如下 1.页面加载时,根据getLocation方法获取用户当前经纬度获取20条医院位置信息 2.页面滑动时,根据滑动到的经纬度再次获取20条医院位置信息 获取到的医院位置信息 实现方法如下 1.在.wxml中添加触发滑动的方法bindregiοnchange“onMapRegio…

黑马点评笔记 redis缓存三大问题解决

文章目录 缓存问题缓存穿透问题的解决思路编码解决商品查询的缓存穿透问题 缓存雪崩问题及解决思路缓存击穿问题及解决思路问题分析使用锁来解决代码实现 逻辑过期方案代码实现 缓存问题 我们熟知的是用到缓存就会遇到缓存三大问题: 缓存穿透缓存击穿缓存雪崩 接…

XDR 网络安全:技术和最佳实践

扩展检测和响应(XDR)是一种安全方法,它将多种保护工具集成到一个统一的集成解决方案中。它为组织提供了跨网络、端点、云工作负载和用户的广泛可见性,从而实现更快的威胁检测和响应。 XDR的目标是提高威胁检测的速度和准确性&…

【C语言】memset函数

memset是C和C编程语言中的一个函数&#xff0c;用于将指定的内存区域设置为特定的值。这个函数的原型在<string.h>&#xff08;对于C&#xff09;或者<cstring>&#xff08;对于C&#xff09;头文件中定义。 函数原型如下&#xff1a; void *memset(void *str, i…

14 redis全量复制与部分复制

1、设置主服务器的地址和端口 首先是在从服务器设置需要同步的主服务器信息&#xff0c;包括机器IP, 端口。 主从复制的开启&#xff0c;完全是在从节点发起的。不需要我们在主节点做任何事情。 从节点开启主从复制&#xff0c;有3种方式 配置文件&#xff1a;在从服务器的配…

机器人制作开源方案 | 智能图书搬运机器人

作者&#xff1a;张宸豪 戚益凡 陈世达 高梓钦 谭清 单位&#xff1a;华北科技学院 指导老师&#xff1a;罗建国 韩红利 阅读对于学生的重要性毋庸置疑&#xff0c;因此图书馆是一个校园非常重要的组成部分&#xff0c;图书馆的书籍借阅&#xff0c;能为学生提供非常大的…

【LeetCode刷题-链表】--61.旋转链表

61.旋转链表 方法&#xff1a; 记给定的链表的长度为n,注意当向右移动的次数k>n时&#xff0c;仅需要向右移动k mod n次即可&#xff0c;因为每n次移动都会让链表变为原状 将给定的链表连接成环&#xff0c;然后将指定位置断开 /*** Definition for singly-linked list.*…

性能相关的闪存特性

一、多Plane操作 上章提到若干个Plane组成Die或者叫LUN,即一个Die上有多个Plane 每次进行写操作时&#xff0c;控制器先将数据写入页缓存中&#xff0c;等同一个Die上另一个Plane也写数据的时候&#xff0c;再同时写入&#xff0c;原来单独操作一个Plane的时间变成了可以同时做…