Netty之ByteBuf

Netty之ByteBuf一、功能原理ByteBuf是一个byte存放的缓冲区。ByteBuf通过两个位置的指针来协助缓冲区的读写操作,读操作使用readIndex,写操作使用writeIndex。+——————-+——————+——————+|discardablebytes|readablebytes

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

一、功能原理

ByteBuf是一个byte存放的缓冲区。

ByteBuf通过两个位置的指针来协助缓冲区的读写操作,读操作使用readIndex,写操作使用writeIndex。

+-------------------+------------------+------------------+
| discardable bytes |  readable bytes  |  writable bytes  |
|                   |     (CONTENT)    |                  |
+-------------------+------------------+------------------+
|                   |                  |                  |
0      <=      readerIndex   <=   writerIndex    <=    capacity
discardable bytes 丢弃的读空间
readable bytes 可读空间
writeable bytes 可写空间

比如:

ByteBuf heapBuffer = Unpooled.buffer();
System.out.println(heapBuffer);
结果:
UnpooledHeapByteBuf(ridx: 0, widx: 0, cap: 256)
ridx是readerIndex读取数据索引,位置从0开始
widx是writeIndex写数据索引,位置从0开始
cap是capacity缓冲区初始化的容量,默认256,可以通过Unpooled.buffer(8)设置,初始化缓冲区容量是8。

如果写入内容超过cap,cap会自动增加容量,但不能超过缓冲区最大容量maxCapacity。
ByteBuf heapBuffer = Unpooled.buffer(8);
System.out.println("初始化:"+heapBuffer);
heapBuffer.writeBytes("测试测试测试");
System.out.println("写入测试测试测试:"+heapBuffer);

结果:

初始化:UnpooledHeapByteBuf(ridx: 0, widx: 0, cap: 8)
写入测试测试测试:UnpooledHeapByteBuf(ridx: 0, widx: 18, cap: 64)

cap初始化8,增加到64


缓冲内容复制到字节数组
//1、创建缓冲区
ByteBuf heapBuffer = Unpooled.buffer(8);
		
//2、写入缓冲区内容
heapBuffer.writeBytes("测试测试测试".getBytes());
		
//3、创建字节数组
byte[] b = new byte[heapBuffer.readableBytes()];
		
System.out.println(b[11]);
		
//4、复制内容到字节数组b
heapBuffer.readBytes(b);
		
System.out.println(b[11]);
		
//5、字节数组转字符串
String str = new String(b);
		
System.out.println(str);

结果:

0
-107
测试测试测试

ByteBuf转ByteBuffer

ByteBuffer bb = heapBuffer.nioBuffer();

ByteBuf的主要类继承关系图

Netty之ByteBuf


从内存分配的角度看,ByteBuf可以分为两类:

1、堆内存(HeapByteBuf)字节缓冲区:特点是内存的分配和回收速度快,可以被JVM自动回收;缺点就是如果进行Socket的IO读写,需要额外做一次内存复制,将堆内存对应的缓冲区复制到内核Channel中,性能会有一定程度的下降

2、直接内存(DirectByteBuf) 字节缓冲区:非堆内存,它在对外进行内存分配,相比于堆内存,它的分配和回收速度会慢一些,但是将它写入或者从Socket Channel中读取时,由于少一次内存复制,速度比堆内存快

Netty的最佳实践是在I/O通信线程的读写缓冲区使用DirectByteBuf,后端业务消息的编解码模块使用HeapByteBuf,这样组合可以达到性能最优。

ByteBuf的四种声明方式
ByteBuf heapBuffer = Unpooled.buffer();
System.out.println(heapBuffer);
		
ByteBuf directBuffer = Unpooled.directBuffer();
System.out.println(directBuffer);
		
ByteBuf wrappedBuffer = Unpooled.wrappedBuffer(new byte[128]);
System.out.println(wrappedBuffer);
		
ByteBuf copiedBuffer = Unpooled.copiedBuffer(new byte[128]);
System.out.println(copiedBuffer);

结果:

UnpooledHeapByteBuf(ridx: 0, widx: 0, cap: 256)
SimpleLeakAwareByteBuf(UnpooledUnsafeDirectByteBuf(ridx: 0, widx: 0, cap: 256))
UnpooledHeapByteBuf(ridx: 0, widx: 128, cap: 128/128)
UnpooledHeapByteBuf(ridx: 0, widx: 128, cap: 128/128)

未完,待续



版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/191804.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 常量池和堆的区别_字符串常量池在堆中还是方法区

    常量池和堆的区别_字符串常量池在堆中还是方法区写在前面:博主是一位普普通通的19届二本大学生,平时最大的爱好就是听听歌,逛逛B站。博主很喜欢的一句话花开堪折直须折,莫待无花空折枝:博主的理解是头一次为人,就应该做自己想做的事,做自己不后悔的事,做自己以后不会留有遗憾的事,做自己觉得有意义的事,不浪费这大好的青春年华。博主写博客目的是记录所学到的知识并方便自己复习,在记录知识的同时获得部分浏览量,得到更多人的认可,满足小小的成就感,同时在写博客的途中结交更多志同道合的朋友,让自己在技术的路上并不孤单。目录:1.常量池与Class常量池2.运.

    2022年7月28日
    11
  • Arduino智能小车设计(一)「建议收藏」

    Arduino智能小车设计(一)「建议收藏」这一个月来距离实验室纳新后,已经过去一个月左右了。听取了学长的建议,这段时间也一直在搞Arduino这个软件,还算不错的认识了这个开源软件。(自我认为。。)但是现在的依旧是一个小萌新,不说在软件代码的掌握程度,现在连有些最基本的硬件的名字也都叫不上来几个。。。不过还好,自己也不是单打独斗,通过和同组成员的讨论也还算是一点一点进步吧。最幸运的是,每次我遇到不会的东西,他们都可以帮我解答。从今天…

    2022年10月17日
    4
  • JDBC连接数据库6个步骤

    JDBC连接数据库6个步骤JDBC连接数据库,创建一个以JDBC连接数据库的程序,包含7个步骤:   首先准备JDBC所需的四个参数(user,password,url,driverClass)(1)user用户名(2)password密码(3)URL定义了连接数据库时的协议、子协议、数据源标识,它们之间用冒号隔开。  书写形式:  协议:子协议:数据源标识       协议:在JDBC中总是以jdb…

    2022年7月12日
    15
  • Android开发Service之BindService

    Android开发Service之BindService前言一直使用Qt来进行桌面端和移动端开发,对Android开发并不熟悉,但是项目中往往又经常会用到Android原生开发的东西。本次收集了一些关于BindService相关的知识供自己学习和参考。正文bindService介绍一、bindService简介bindService是绑定Service服务,执行service服务中的逻辑流程。service通过C…

    2022年6月5日
    36
  • iOS_11_tableViewCell使用alertView变更数据

    iOS_11_tableViewCell使用alertView变更数据

    2022年1月2日
    40
  • 有两个表A和B,均有key和value两个字段,如果B的key在A中也有,就把B的value替换为A中对应的value

    有两个表A和B,均有key和value两个字段,如果B的key在A中也有,就把B的value替换为A中对应的value

    2021年11月22日
    49

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号