ByteBuffer的原理和使用详解

ByteBuffer是字节缓冲区,主要用户读取和缓存字节数据,多用于网络编程,原生的类,存在不好用,Netty采用自己的ByteBuff,对其进行了改进

1.ByteBuffer的2种创建方式


1.ByteBuffer buf = ByteBuffer.allocate(int size);
方式1的buf缓冲区存储在堆内存中,内存开销在JVM中,受GC影响,会多拷贝一次,因为java程序收到的数据首先被系统内存所获取,然后再拷贝给JVM

2.ByteBuffer buf = ByteBuffer.allocateDirect(int size);
方式2的buf在系统直接内存中创建,内存开销在JVM之外,读写效率高(不受GC影响,0拷贝),但是分配效率低,使用后若不释放,会造成内存泄漏

下图是不同容量情况下,两种ByteBuffer的读写效率,根据需求选择创建方式:


2.字符串转成ByteBuffer的3三种方式


方式1: 采用put()方法,读数据时需要调用flip()切换为读模式

ByteBuffer buf = ByteBuffer.allocate(int size);buf.put(msg.getBytes());


方式2:以特定编码格式将String转换为ByteBuffer

ByteBuffer buffer1 = StandardCharsets.UTF_8.encode("hello");


方式3:调用ByteBuffer.wrap()

ByteBuffer buf = ByteBuffer.wrap(msg.getBytes());


3.Bytebuffer的读写底层原理


Bytebuffer的数据读写主要采用三个参数来控制

1.position:起始下标
2.limit:限制下标
3.capacity:buffer的容量


核心思想:Bytebuffer的读写共用position、limit参数,因此需要切换至读模式(调用flip())和写模式(调用)

一.开始时,position指向0,limit指向capacity


二.写模式下,写数据时,Position会不断前移

 

三.调用flip()切换为读模式,此时Postion置为已有数据的起始下标,limit置为已有数据的末尾下标

 


四.调用clear()方法切换为写模式,采用清空缓冲区,将potision置为0,limit置为capacity


至此,我们知道读写模式由于共用相同的position等参数,因此,需要切换模式,才能正确的读写。

并且在发生一次写读(先写后读)切换后,需要调用clear()方法进行重置,才能进行一轮新的写读

当然,你可以连续写或连续读,读读或写写可以连续执行,不需要额外操作。例如:

ByteBuffer buf = ByteBuffer.allocate(int size);buf.put(msg.getBytes());  //okbuf.put(msg2.getBytes());  //ok


存在的问题:

读操作后,重新写,调用clear()会重置至0的问题,如果没有读完呢?

例如 存在接收到的数据是不完整的,无法进行读操作,那么需要在原来的基础上,继续写数据怎么办?

答案是 Buffer.compact() 切换到写入模式

五. 调用compact方法切换为写模式,在不清空缓冲区的前提下,继续写如信息,将未读取的数据前移,postion指针置为未读取数据的末尾下标,limit置为capacity


上图左侧灰色是已读部分数据,绿色是未读部分,在此基础上,调用compact继续写,会进行部分清楚操作,同时保留未读部分,这也是推荐的用法。

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

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

相关文章

竞赛 深度学习手势识别 - yolo python opencv cnn 机器视觉

文章目录 0 前言1 课题背景2 卷积神经网络2.1卷积层2.2 池化层2.3 激活函数2.4 全连接层2.5 使用tensorflow中keras模块实现卷积神经网络 3 YOLOV53.1 网络架构图3.2 输入端3.3 基准网络3.4 Neck网络3.5 Head输出层 4 数据集准备4.1 数据标注简介4.2 数据保存 5 模型训练5.1 修…

206.反转链表

206.反转链表 力扣题目链接(opens new window) 题意:反转一个单链表。 示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL 双双指针法: 创建三个节点 pre(反转时的第一个节点)、cur(当前指向需要反转的节点…

GB28181协议如何注册

前言 GB28181协议是视频监控领域的国家标准,本文将解析如何在FFmpeg中增加对GB28181协议的支持,使其可以与支持GB28181协议的设备进行通信与控制,实现设备的注册、保活以及流媒体的传输。 1.背景介绍 GB28181协议指的是国家标准GB/T 28181…

一文带你了解自动化测试是什么?

本章主要讲解自动化测试的含义、分类、项目使用,以及自动化测试工具的优势。 一、自动化测试概述 1、什么是自动化测试? 自动化测试是软件测试活动中的一个重要分支和组成部分。随着软件产业的不断发展,市场对软件周期的要求越来越高&…

Java日志组件介绍之二

一、前言 Java日志组件介绍之一 主要介绍了JDK内置日志和Apache的common-logging通用日志接口,今天这篇我们继续了解Java其它一些日志组件。 二、slf4j slf4j即Simple Logging Facade for JAVA ,简单日志门面,类似common-logging&#xff0…

基于ASP.NET MVC + Bootstrap的仓库管理系统

基于ASP.NET MVC Bootstrap的仓库管理系统。源码亲测可用,含有简单的说明文档。 适合单仓库,基本的仓库入库管理,出库管理,盘点,报损,移库,库位等管理,有着可视化图表。 系统采用Bo…

Kubernetes - Ingress HTTP 升级 HTTPS 配置解决方案(新版本v1.21+)

之前我们讲解过 Kubernetes - Ingress HTTP 搭建解决方案,并分别提供了旧版本和新版本。如果连 HTTP 都没搞明白的可以先去过一下这两篇 Kubernetes - Ingress HTTP 负载搭建部署解决方案_放羊的牧码的博客-CSDN博客Kubernetes - Ingress HTTP 负载搭建部署解决方案…

17.基干模型Swin-Transformer解读

文章目录 SWin-Transformer解读1.基础介绍关于Shifted Window based Self-Attention相对位置偏置网络整体结构和层级特征欢迎访问个人网络日志🌹🌹知行空间🌹🌹 SWin-Transformer解读 1.基础介绍 Swin-Transformer是2021年03月微软亚洲研究院提交的论文中提出的,比V…

八段流水线运行示意图

流水线如下图所示: 存储周期存取时间恢复时间, 即存取完数据后需要一定量的时间来恢复, 而低位交叉编址的流水线所利用的正是恢复时间 流水线与非流水线对比如下: 经典例题: 2013年408真题

全网最全的RDMA拥塞控制入门基础教程

RDMA-CC(全网最全的RDMA拥塞控制入门基础教程) 文章目录 RDMA-CC(全网最全的RDMA拥塞控制入门基础教程)DMARDMARDMA举例RDMA优势RDMA的硬件实现方法RDMA基本术语FabricCA(Channel Adapter)Verbs 核心概念Me…

UE5 Android下载zip文件并解压缩到指定位置

一、下载是使用市场的免费插件 二、解压缩是使用市场的免费插件 三、Android路径问题 windows平台下使用该插件没有问题,只是在Android平台下,只有使用绝对路径才能进行解压缩,所以如何获得Android下的绝对路径?增加C文件获得And…

众和策略:微软大动作

当地时间周二,美股首要指数全线收涨。但从月度数据来看,美股首要指数录得“三连跌”,10月份,道指跌1.36%,标普500指数跌2.2%,纳指跌2.78%。其间,标普和道指均为2020年3月以来初次呈现三个月连跌…