05-netty基礎-ByteBuf數據結構

1 基本概念

在網絡編程中,字節數據的處理是核心環節之一。無論是客戶端與服務器之間的通信,還是數據的編解碼操作,都離不開對字節緩沖區的高效管理。Java 原生的?ByteBuffer?雖然提供了基礎功能,但在靈活性、性能和易用性上存在諸多局限。而 Netty 框架提供的?ByteBuf?則徹底解決了這些問題,成為處理網絡字節數據的首選工具。

2 為什么需要?Bytebuf

Java 原生的?ByteBuffer?存在以下明顯短板:

  • 單指針設計:僅有一個?position?指針,讀寫操作需頻繁調用?flip()?切換模式,容易出錯;
  • 固定容量:創建后容量不可動態調整,超出容量時需手動擴容,操作繁瑣;
  • 內存管理復雜:堆外內存(直接內存)的釋放依賴 GC,可能導致內存泄漏;
  • API 設計不友好:缺乏直接讀寫基本類型、字符串的便捷方法。

相比之下,ByteBuf?針對網絡編程場景進行了全面優化:

  • 采用雙指針設計,讀寫無需切換模式;
  • 支持自動擴容,無需手動處理容量不足問題;
  • 內置引用計數機制,精準控制內存生命周期;
  • 提供豐富的 API,簡化字節數據操作。

3?Bytebuf數據結構

?3.1 創建一個空Bytebuf

 public static void main(String[] args) {// 空ByteBufemptyByteBuf();}private static void emptyByteBuf() {// byteBuf 分配一塊內存,自動判斷是否分配堆內存或者堆外內存ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer();printMsg(byteBuf);}private static void printMsg(ByteBuf byteBuf) {StringBuilder stringBuilder = new StringBuilder();stringBuilder.append("read index:").append(byteBuf.readerIndex()).append("\n");stringBuilder.append("write index:").append(byteBuf.writerIndex()).append("\n");stringBuilder.append("capacity:").append(byteBuf.capacity()).append("\n");stringBuilder.append("maxCapacity:").append(byteBuf.maxCapacity()).append("\n");ByteBufUtil.appendPrettyHexDump(stringBuilder, byteBuf);System.out.println(stringBuilder.toString());}

輸出

read index:0
write index:0
capacity:256
maxCapacity:2147483647?

數據為空時bytebuf的內存結構

3.2 往Bytebuf中寫入數據?

 private static void writeByte() {// byteBuf 分配一塊內存,自動判斷是否分配堆內存或者堆外內存ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer();// 寫入1個字節byteBuf.writeBytes(new byte[]{(byte)1});printMsg(byteBuf);}private static void printMsg(ByteBuf byteBuf) {StringBuilder stringBuilder = new StringBuilder();stringBuilder.append("read index:").append(byteBuf.readerIndex()).append("\n");stringBuilder.append("write index:").append(byteBuf.writerIndex()).append("\n");stringBuilder.append("capacity:").append(byteBuf.capacity()).append("\n");stringBuilder.append("maxCapacity:").append(byteBuf.maxCapacity()).append("\n");ByteBufUtil.appendPrettyHexDump(stringBuilder, byteBuf);System.out.println(stringBuilder.toString());}

read index:0
write index:1
capacity:256
maxCapacity:2147483647
+-------------------------------------------------+
| ?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9 ?a ?b ?c ?d ?e ?f |
+--------+-------------------------------------------------+----------------+
|00000000| 01 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?|. ? ? ? ? ? ? ? |
+--------+-------------------------------------------------+----------------+

?寫入1個字節內存結構

3.3?Bytebuf中讀取數據??

private static void readByte() {// byteBuf 分配一塊內存,自動判斷是否分配堆內存或者堆外內存ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer();// 寫入1個字節byteBuf.writeBytes(new byte[]{(byte)1, (byte)2});printMsg(byteBuf);// 讀取1個字節byte b = byteBuf.readByte();printMsg(byteBuf);}private static void printMsg(ByteBuf byteBuf) {StringBuilder stringBuilder = new StringBuilder();stringBuilder.append("read index:").append(byteBuf.readerIndex()).append("\n");stringBuilder.append("write index:").append(byteBuf.writerIndex()).append("\n");stringBuilder.append("capacity:").append(byteBuf.capacity()).append("\n");stringBuilder.append("maxCapacity:").append(byteBuf.maxCapacity()).append("\n");ByteBufUtil.appendPrettyHexDump(stringBuilder, byteBuf);System.out.println(stringBuilder.toString());}

read index:0
write index:2
capacity:256
maxCapacity:2147483647
+-------------------------------------------------+
| ?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9 ?a ?b ?c ?d ?e ?f |
+--------+-------------------------------------------------+----------------+
|00000000| 01 02 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |.. ? ? ? ? ? ? ?|
+--------+-------------------------------------------------+----------------+
read index:1
write index:2
capacity:256
maxCapacity:2147483647
+-------------------------------------------------+
| ?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9 ?a ?b ?c ?d ?e ?f |
+--------+-------------------------------------------------+----------------+
|00000000| 02 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?|. ? ? ? ? ? ? ? |
+--------+-------------------------------------------------+----------------+

?

?3.4 Bytebuf讀取后重復讀取

 public static void main(String[] args) {// jvm堆內存ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer();// 寫數據byteBuf.maxWritableBytes();byteBuf.writeBytes(new byte[] {1, 2, 3, 4});printMsg(byteBuf);// 重置,寫指針復位到起始位置重新寫入,覆蓋寫byteBuf.resetWriterIndex();byteBuf.writeInt(6);printMsg(byteBuf);// 讀byteBuf.markReaderIndex();byte a = byteBuf.readByte();byte b = byteBuf.readByte();byteBuf.resetReaderIndex();printMsg(byteBuf);}private static void printMsg(ByteBuf byteBuf) {StringBuilder stringBuilder = new StringBuilder();stringBuilder.append("read index:").append(byteBuf.readerIndex()).append("\n");stringBuilder.append("write index:").append(byteBuf.writerIndex()).append("\n");stringBuilder.append("capacity:").append(byteBuf.capacity()).append("\n");stringBuilder.append("maxCapacity:").append(byteBuf.maxCapacity()).append("\n");ByteBufUtil.appendPrettyHexDump(stringBuilder, byteBuf);System.out.println(stringBuilder.toString());}

read index:0
write index:4
capacity:256
maxCapacity:2147483647
+-------------------------------------------------+
| ?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9 ?a ?b ?c ?d ?e ?f |
+--------+-------------------------------------------------+----------------+
|00000000| 01 02 03 04 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |.... ? ? ? ? ? ?|
+--------+-------------------------------------------------+----------------+
read index:0
write index:8
capacity:256
maxCapacity:2147483647
+-------------------------------------------------+
| ?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9 ?a ?b ?c ?d ?e ?f |
+--------+-------------------------------------------------+----------------+
|00000000| 01 02 03 04 01 02 03 04 ? ? ? ? ? ? ? ? ? ? ? ? |........ ? ? ? ?|
+--------+-------------------------------------------------+----------------+
read index:0
write index:4
capacity:256
maxCapacity:2147483647
+-------------------------------------------------+
| ?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9 ?a ?b ?c ?d ?e ?f |
+--------+-------------------------------------------------+----------------+
|00000000| 00 00 00 06 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |.... ? ? ? ? ? ?|
+--------+-------------------------------------------------+----------------+

?

?備注:markWriterIndex、resetWriterIndex一般是配套使用,如果未標記寫指針的位置默認從起始位置開始;markReaderIndex、resetReaderIndex一般也是配套使用,如果未標記讀取的位置,則從起始位置重新讀取

4 Bytebuf擴容

  1. 初始嘗試:如果?minNewCapacity?小于等于 4MB(4194304?字節),新容量為大于等于?minNewCapacity?的最小 2 的冪;
  2. 超過 4MB 時:如果?minNewCapacity?大于 4MB,新容量為大于等于?minNewCapacity?且為 4MB 整數倍的值;
  3. 上限控制:新容量不能超過?ByteBuf?的最大容量。

案例: 未超過4M,成倍增長

public class ByteBufCapacity {public static void main(String[] args) {// jvm堆內存ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer();for (int i=0; i<256; i++) {byteBuf.writeBytes(new byte[] {(byte) i});}printMsg(byteBuf);for (int i=0; i<256; i++) {byteBuf.writeBytes(new byte[] {(byte) i});}printMsg(byteBuf);}private static void printMsg(ByteBuf byteBuf) {StringBuilder stringBuilder = new StringBuilder();stringBuilder.append("read index:").append(byteBuf.readerIndex()).append("\n");stringBuilder.append("write index:").append(byteBuf.writerIndex()).append("\n");stringBuilder.append("capacity:").append(byteBuf.capacity()).append("\n");stringBuilder.append("maxCapacity:").append(byteBuf.maxCapacity()).append("\n");
//        ByteBufUtil.appendPrettyHexDump(stringBuilder, byteBuf);System.out.println(stringBuilder.toString());}

read index:0
write index:256
capacity:256
maxCapacity:2147483647

read index:0
write index:512
capacity:512
maxCapacity:2147483647

?大于4M,每次增加4M擴容

package com.bonnie.netty.bytebuf;import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;public class ByteBufCapacity {public static void main(String[] args) {// jvm堆內存ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer();// 4Mfor (int i=0; i<4194304; i++) {byteBuf.writeBytes(new byte[] {(byte) i});}printMsg(byteBuf);// 擴容+4Mfor (int i=0; i<4194304; i++) {byteBuf.writeBytes(new byte[] {(byte) i});}printMsg(byteBuf);// 擴容+4Mfor (int i=0; i<4194304; i++) {byteBuf.writeBytes(new byte[] {(byte) i});}printMsg(byteBuf);}private static void printMsg(ByteBuf byteBuf) {StringBuilder stringBuilder = new StringBuilder();stringBuilder.append("read index:").append(byteBuf.readerIndex()).append("\n");stringBuilder.append("write index:").append(byteBuf.writerIndex()).append("\n");stringBuilder.append("capacity:").append(byteBuf.capacity()).append("\n");stringBuilder.append("maxCapacity:").append(byteBuf.maxCapacity()).append("\n");
//        ByteBufUtil.appendPrettyHexDump(stringBuilder, byteBuf);System.out.println(stringBuilder.toString());}}

read index:0
write index:4194304
capacity:4194304
maxCapacity:2147483647

read index:0
write index:8388608
capacity:8388608
maxCapacity:2147483647

read index:0
write index:12582912
capacity:12582912
maxCapacity:2147483647

?5 堆內存和堆外內存

實堆內的意思就是java虛擬機里面的堆空間,而堆外的意思是java進程中系統 為它分配的堆空間,jvm堆中的數據如果想要寫入磁盤,就會進行write系統調用,調用過程為:jvm堆->系統 堆->PageCache->磁盤,如果數據是放在系統heap中,調用過程為:系統堆->PageCache->磁盤。 我們可以看到,使用堆內內存寫入數據會少一次的拷貝次數

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/91582.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/91582.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/91582.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Nginx反向代理】通過Nginx反向代理將多個后端server統一到同一個端口上的方法

文章目錄前言解決方案&#xff1a;使用 Nginx 做統一反向代理前言 在多人開發任務中&#xff0c;如果不同人負責不同的后端接口服務開發&#xff0c;那么就面臨著每個人的服務部署到不同的端口上&#xff0c;甚至有的人的服務部署在不同的服務器上。這時候前端如果想要調用后端…

Chrontel【CH7219A-BF】CH7219A USB-C和DP 1.4至HDMI 2.1協議轉換器,帶DSC解碼功能

G通用 D描述Chrontel 的 CH7219A 是一種低成本、低功耗的半導體器件 通過 USB Type-C 將 DisplayPort 信號轉換為 HDMI 2.0 連接器。這款基于 USB Type-C 的創新型 DisplayPort 接收器具有高 高性能DSC解碼器&#xff0c;集成HDMI 2.0發射器 專為 USB Type-C 轉 HDMI 2.0 轉換器…

瘋狂星期四文案網第26天運營日記

網站運營第26天&#xff0c;點擊觀站&#xff1a; 瘋狂星期四 crazy-thursday.com 全網最全的瘋狂星期四文案網站 運營報告 今日訪問量 30多ip,斷崖式下跌&#xff0c;習慣了。。 今日搜索引擎收錄情況 必應52個頁面&#xff0c;比昨日12 百度仍然只有首頁 谷歌收錄正常 …

元策聯盈:深耕金融領域,賦能行業發展?

元策聯盈&#xff1a;深耕金融領域&#xff0c;賦能行業發展元策聯盈在金融行業的深耕細作&#xff0c;不僅體現在為客戶提供優質服務上&#xff0c;更在于其對行業發展的積極推動和自身的不斷創新突破。行業貢獻與社會責任元策聯盈始終將社會責任融入企業發展的血脈之中。在助…

力扣-字母異位詞

這里我也是沒有太懂&#xff0c;只懂個大概&#xff0c;先統計p和當前窗口的字符&#xff0c;后主要在窗口大小固定為 p.length()&#xff0c;在 s 上滑動做文章&#xff0c;在s里找到p的長度大小&#xff0c;最后直接比較兩個頻率數組來判斷異位詞定長窗口做法class Solution …

華為數通HCIP

華為認證數通方向的 HCIP&#xff08;華為認證 ICT 高級工程師&#xff09;考試難度適中&#xff0c;既不像 HCIA&#xff08;初級&#xff09;那樣側重基礎概念&#xff0c;也不像 HCIE&#xff08;專家級&#xff09;需要復雜的綜合實驗和面試&#xff0c;但仍需要系統的知識…

在SQL SERVER 中,用SSMS 實現存儲過程的每日自動調用

在 SQL Server Management Studio (SSMS) 中實現每日自動調用存儲過程&#xff0c;需通過 ??SQL Server 代理作業??配置定時任務。以下是詳細操作步驟&#xff1a;&#x1f527; 一、啟用 SQL Server 代理服務&#xff08;前置條件&#xff09;??啟動服務??&#xff1a…

賽博算命之八字測算事業運勢的Java實現(四柱、五行、十神、流年、格局詳細測算)

個人主頁-愛因斯晨 文章專欄-賽博算命 最近學習人工智能時遇到一個好用的網站分享給大家&#xff1a; 人工智能學習 文末有投票&#xff0c;評論區有紅包哦&#xff01; 前言 在前段時間更新了賽博算命系列&#xff0c;出乎我的意料反響很好。也受到廣大網友的贊賞&#xff0…

2025 騰訊廣告算法大賽 Baseline 項目解析

項目概述 2025 騰訊廣告算法大賽 Baseline&#xff0c;一個簡單的序列推薦系統&#xff0c;主要用于建模用戶和物品的交互序列&#xff0c;并利用多模態特征&#xff08;文本、圖像等 embedding&#xff09;來提升推薦效果。 核心文件功能 1. main.py - 主訓練腳本 負責模型訓練…

數據結構(11)棧和隊列算法題 OVA

一、概念與結構 循環隊列是一種特殊的隊列&#xff0c;首尾相連成環&#xff0c;也叫環形隊列。環形隊列具有以下三個特點&#xff1a; &#xff08;1&#xff09;隊頭刪除數據&#xff0c;隊尾插入數據。 &#xff08;2&#xff09;給定固定的空間&#xff0c;使用過程中不…

九聯UNT403HS_海思MV320處理器_安卓9-優盤強刷刷機包

九聯UNT403HS_海思MV320處理器_安卓9-優盤強刷刷機包前言&#xff1a;九聯UNT403HS&#xff0c;海思MV320芯片&#xff0c;已知有2種內存型號&#xff0c;分別是28G和216G。已知河南融合版本是28G&#xff0c;廣東版好像既有28G又有216G。理論上固件沒有本質區分&#xff0c;能…

Xilinx高性能低延時PCIe-DMA控制器IP,SGDMA,QDMA,RDMA,CDMA,V4L2驅動,視頻采集、AD采集

Multi-Channel High Performance PCIe QDMA&RDMA IP介紹基于PCI Express Integrated Block&#xff0c;Multi-Channel PCIe QDMA Subsystem實現了使用DMA地址隊列的獨立多通道、高性能Continous&#xff08;CDMA&#xff09;或Scather Gather DMA&#xff08;SGDMA&#xf…

10、Docker Compose 安裝 MySQL

&#x1f433; 使用 Docker Compose 安裝 MySQL&#xff08;含配置詳解與常見問題&#xff09;標簽&#xff1a;#DockerCompose #MySQL #數據庫部署 #后端開發 #運維入門 #配置詳解 適合讀者&#xff1a;開發者、DevOps、新手運維人員&#x1f4cc; 一、前言 在日常開發與部署中…

Dynamic A(D)算法深度剖析:動態環境下的路徑規劃革新

Dynamic A*(D*)算法深度剖析:動態環境下的路徑規劃革新 文章目錄 Dynamic A*(D*)算法深度剖析:動態環境下的路徑規劃革新 1. 引言:動態路徑規劃的核心挑戰與解決方案 1.1 動態環境的本質特征 1.2 D * 算法的誕生與核心價值 2. D * 算法核心原理深度解析 2.1 反向搜索機制…

前端框架Vue3(四)——組件通信及其他API

組件通信組件關系傳遞方式父傳子1. props2. v-model3. $refs4. 默認插槽、具名插槽子傳父1.props2.自定義事件3.v-model4.parent5.作用域插槽祖傳孫、孫傳祖1.$attrs2.provide、inject兄弟間、任意組件間1.mitt2.pinia【props】 概述&#xff1a;props是使用頻率最高的一種通信…

07【C++ 初階】類和對象(中篇) --- 類的默認成員函數

文章目錄前言類的6個默認成員函數1.構造函數1.1 構造函數特性1.1.1 函數名與類名相同1.1.2 無返回值1.1.3 對象實例化時編譯器自動調用對應的構造函數1.1.4 構造函數可以重載1.1.5 默認構造只能有一個1.1.6 默認構造的必要性1.2 構造函數的初始化列表2.析構函數2.1 析構函數特性…

第二次CISSP考試通過!

今天我終于臨時通過了 CISSP 考試&#xff01;這第二次的精神壓力一點也不比第一次小。我在第 101 道題 時通過&#xff0c;還剩大約 30 分鐘。我當時真的以為自己又要像上次那樣時間不夠了。第一次考試的失敗經歷&#xff1a;第一次考試是我剛參加完為期 5 天的強化 Boot Camp…

USRP捕獲手機/路由器數據傳輸信號波形(上)

目錄&#xff1a; USRP捕獲手機/路由器數據傳輸信號波形&#xff08;上&#xff09; USRP捕獲手機/路由器數據傳輸信號波形&#xff08;中&#xff09; USRP捕獲手機/路由器數據傳輸信號波形&#xff08;下&#xff09; 一、前期準備 1.1 場景與系統 手機、路由器與天線的…

基于STM32F103的FM1702驅動程序

基于STM32F103微控制器與復旦微電子FM1702SL射頻讀卡芯片的驅動開發方案&#xff0c;整合了硬件配置、寄存器操作和通信協議實現&#xff1a;一、硬件連接設計 1. 管腳映射表FM1702SL引腳STM32F103引腳功能說明VDD3.3V電源輸入GNDGND地線SCKPA5(SPI1_SCK)SPI時鐘MISOPA6(SPI1_M…

京東商品評論API指南

一、引言京東商品評論API(JD.item_review)是京東開放平臺提供的重要接口&#xff0c;允許開發者獲取商品的詳細評論數據。通過該接口可以獲取包括評論內容、評分、評論時間、用戶昵稱等信息&#xff0c;為商品分析、用戶行為研究等提供數據支持?。二、接口概述1. 接口基本信息…