Netty:ByteBuf的資源釋放方法

說明

io.netty.buffer.ByteBuf實現了io.netty.util.ReferenceCounted接口,需要顯式釋放。當ByteBuf被實例化后,它的引用計數是1。

調用ByteBuf對象的release方法釋放:

  • ByteBuf的release()方法使引用計數減少1。只有當執行以后引用計數減少到0,該函數才返回true。當ByteBuf的引用計數減少到0時,ByteBuf會被釋放。
  • 當ByteBuf的引用計數是0時,再執行release()方法會拋出IllegalReferenceCountException異常。

調用ReferenceCountUtil的方法釋放:

  • release(Object msg):如果要被釋放的對象msg實現了ReferenceCounted接口,那么內部會調用該對象的release()方法,并返回執行release()方法的結果。如果要被釋放的對象msg沒有實現ReferenceCounted接口,那么直接返回false。
  • safeRelease(Object msg):當要被釋放的對象實現了ReferenceCounted接口,內部調用對象的release()方法來釋放;如果對象的當前引用計數是0時,如果執行該函數,不會拋出異常,而是打印告警日志。如果要被釋放的對象沒有實現ReferenceCounted接口,執行該函數不會有任何作用。

代碼示例

執行ByteBuf的release()返回結果觀察

package com.thb;import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;public class Demo {public static void main(String[] args) {// 創建一個ByteBufByteBuf buf = Unpooled.buffer();// 引用計數加1buf.retain();// 此時的引用計數是2System.out.println("buf.refCnt: " + buf.refCnt());// 此時執行buf.release()返回false,因為執行以后的引用計數變成1System.out.println("buf.release: " + buf.release());// 此時的引用計數是1System.out.println("buf.refCnt: " + buf.refCnt());System.out.println("buf.release: " + buf.release());// 此時執行buf.release()返回true,因為執行以后的引用計數變成0System.out.println("buf.refCnt: " + buf.refCnt());		}}

運行輸出:

buf.refCnt: 2
buf.release: false
buf.refCnt: 1
buf.release: true
buf.refCnt: 0

ByteBuf的引用計數是0時,再執行release()方法會拋出IllegalReferenceCountException異常

package com.thb;import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;public class Demo {public static void main(String[] args) {// 創建一個ByteBufByteBuf buf = Unpooled.buffer();// 此時的引用計數是1System.out.println("buf.refCnt: " + buf.refCnt());// 此時執行buf.release()返回true,因為執行以后的引用計數變成0System.out.println("buf.release: " + buf.release());// 此時的引用計數是0System.out.println("buf.refCnt: " + buf.refCnt());// ByteBuf的引用計數已經變成0,再執行release()函數會拋出IllegalReferenceCountException異常System.out.println("buf.release: " + buf.release());}}

運行結果:

buf.refCnt: 1
buf.release: true
buf.refCnt: 0
Exception in thread "main" io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1at io.netty.util.internal.ReferenceCountUpdater.toLiveRealRefCnt(ReferenceCountUpdater.java:83)at io.netty.util.internal.ReferenceCountUpdater.release(ReferenceCountUpdater.java:148)at io.netty.buffer.AbstractReferenceCountedByteBuf.release(AbstractReferenceCountedByteBuf.java:101)at com.thb.Demo.main(Demo.java:19)

調用ReferenceCountUtil的release(Object msg)方法釋放

package com.thb;import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.util.ReferenceCountUtil;public class Demo {public static void main(String[] args) {// 創建一個ByteBufByteBuf buf = Unpooled.buffer();// 此時的引用計數是1System.out.println("buf.refCnt: " + buf.refCnt());// 此時執行ReferenceCountUtil.release(buf)返回true,因為執行以后的引用計數變成0System.out.println("ReferenceCountUtil.release: " + ReferenceCountUtil.release(buf));// 此時的引用計數是0System.out.println("buf.refCnt: " + buf.refCnt());}}

運行輸出:

buf.refCnt: 1
ReferenceCountUtil.release: true
buf.refCnt: 0

用ReferenceCountUtil的release(Object msg)釋放一個引用計數為0的對象,拋出異常

package com.thb;import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.util.ReferenceCountUtil;public class Demo {public static void main(String[] args) {// 創建一個ByteBufByteBuf buf = Unpooled.buffer();// 此時的引用計數是1System.out.println("buf.refCnt: " + buf.refCnt());// 此時返回true,因為執行以后的引用計數變成0System.out.println("ReferenceCountUtil.release: " + ReferenceCountUtil.release(buf));// 此時的引用計數是0System.out.println("buf.refCnt: " + buf.refCnt());// 拋出異常,因為在執行調用前,buf當前的引用計數已經是0了System.out.println("ReferenceCountUtil.release: " + ReferenceCountUtil.release(buf));}}

運行輸出:

buf.refCnt: 1
Exception in thread "main" io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1at io.netty.util.internal.ReferenceCountUpdater.toLiveRealRefCnt(ReferenceCountUpdater.java:83)at io.netty.util.internal.ReferenceCountUpdater.release(ReferenceCountUpdater.java:148)at io.netty.buffer.AbstractReferenceCountedByteBuf.release(AbstractReferenceCountedByteBuf.java:101)at io.netty.util.ReferenceCountUtil.release(ReferenceCountUtil.java:90)at com.thb.Demo.main(Demo.java:21)
ReferenceCountUtil.release: true
buf.refCnt: 0

調用ReferenceCountUtil的release(Object msg)方法釋放一個沒有實現ReferenceCounted接口的對象,結果為false

package com.thb;import io.netty.util.ReferenceCountUtil;public class Demo {public static void main(String[] args) {String msg = "hello";// 此時返回false,因為對象是String類型,沒有實現ReferenceCounted接口System.out.println("ReferenceCountUtil.release: " + ReferenceCountUtil.release(msg));}}

運行輸出:
在這里插入圖片描述

調用ReferenceCountUtil的safeRelease(Object msg)方法釋放實現了ReferenceCounted接口的對象;如果對象當前引用計數為0,打印告警日志

package com.thb;import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.util.ReferenceCountUtil;public class Demo {public static void main(String[] args) {// 創建一個ByteBufByteBuf buf = Unpooled.buffer();// 此時的引用計數是1System.out.println("buf.refCnt: " + buf.refCnt());// 正常釋放ReferenceCountUtil.safeRelease(buf);		// 此時的引用計數是0System.out.println("buf.refCnt: " + buf.refCnt());// buf的引用計數已經在0了,再釋放會打印告警日志ReferenceCountUtil.safeRelease(buf);}}

運行輸出:

buf.refCnt: 1
buf.refCnt: 0
14:55:40.222 [main] WARN  io.netty.util.ReferenceCountUtil - Failed to release a message: UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeHeapByteBuf(freed)
io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1at io.netty.util.internal.ReferenceCountUpdater.toLiveRealRefCnt(ReferenceCountUpdater.java:83) ~[classes/:?]at io.netty.util.internal.ReferenceCountUpdater.release(ReferenceCountUpdater.java:148) ~[classes/:?]at io.netty.buffer.AbstractReferenceCountedByteBuf.release(AbstractReferenceCountedByteBuf.java:101) ~[classes/:?]at io.netty.util.ReferenceCountUtil.release(ReferenceCountUtil.java:90) ~[classes/:?]at io.netty.util.ReferenceCountUtil.safeRelease(ReferenceCountUtil.java:116) [classes/:?]at com.thb.Demo.main(Demo.java:20) [classes/:?]

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

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

相關文章

OpenZFS 2.2 發布 RC3,支持 Linux 6.4

導讀之前的 OpenZFS 2.2 候選版本已致力于實現與 Linux 6.4 內核的兼容性,而在 2.2-rc3 中,Linux 6.4 支持的元跟蹤器已標記為已完成。 OpenZFS 2.2 發布了第 3 個 RC 版本。 之前的 OpenZFS 2.2 候選版本已致力于實現與 Linux 6.4 內核的兼容性&#x…

Vue3 引用第三方Swiper內容觸摸滑動簡單應用

去官網查看更多教程→:Swiper官網 → 點擊教程在vue中使用Swiper→ 在Vue中使用Swiper cd 到項目 安裝Swiper: cnpm install --save swiper 安裝指定版本 cnpm install --save swiper8.1.6 9.4.1 10.1.0…

SpringBoot-Hello World

SpringBootWeb快速入門 創建Springboot工程,并勾選web開發相關依賴定義HelloController類,添加方法hello,并添加相關注釋運行測試 創建新的SpringBoot項目 幾個注意的點: Name:基本上不用管,會根據下面的Ar…

關于elementui的input的autocomplete的使用

項目中需要實現搜索框搜索時能自動提示可選項的功能&#xff0c;elementui的input組件有已經封裝好的el-autocomplete可以使用&#xff0c;但是在使用中發現一些問題&#xff0c;記錄一下 基礎使用 // html部分 <el-autocompletev-model"name":fetch-suggestion…

大數據課程I3——Kafka的消息流與索引機制

文章作者郵箱:yugongshiye@sina.cn 地址:廣東惠州 ▲ 本章節目的 ? 掌握Kafka的消息流處理; ? 掌握Kafka的索引機制; ? 掌握Kafka的消息系統語義; 一、Kafka消息流處理 1. Producer 寫入消息 流程說明: 1. producer 要向Kafka生產消息,需要先通過…

EditPlus連接Linux系統遠程操作文件

EditPlus是一套功能強大的文本編輯器&#xff01; 1.File ->FTP->FTP Settings&#xff1b; 2.Add->Description->FTP server->Username->Password->Subdirectory->Advanced Options 注意&#xff1a;這里的Subdirectory設置的是以后上傳文件的默認…

20230814讓惠普(HP)銳14 新AMD銳龍電腦不聯網進WIN11進系統

20230814讓惠普(HP)銳14 新AMD銳龍電腦不聯網進WIN11進系統 2023/8/14 17:19 win11系統無法跳過聯網 https://www.xpwin7.com/jiaocheng/28499.html Win11開機聯網跳過不了怎么辦&#xff1f;Win11開機聯網跳過不了解決方法 Win11開機聯網跳過不了怎么辦&#xff1f;Win11開機…

Unity框架學習--5 事件中心管理器

作用&#xff1a;訪問其它腳本時&#xff0c;不直接訪問&#xff0c;而是通過發送一條“命令”&#xff0c;讓監聽了這條“命令”的腳本自動執行對應的邏輯。 原理&#xff1a; 1、讓腳本向事件中心添加事件&#xff0c;監聽對應的“命令”。 2、發送“命令”&#xff0c;事件…

【Sklearn】基于支持向量機算法的數據分類預測(Excel可直接替換數據)

【Sklearn】基于支持向量機算法的數據分類預測(Excel可直接替換數據) 1.模型原理1.1 數學模型1.2 模型原理2.模型參數3.文件結構4.Excel數據5.下載地址6.完整代碼7.運行結果1.模型原理 支持向量機(Support Vector Machine,SVM)是一種用于分類和回歸的監督學習算法,其基本…

【Git】安裝以及基本操作

目錄 一、初識Git二、 在Linux底下安裝Git一&#xff09;centOS二&#xff09;Ubuntu 三、 Git基本操作一&#xff09; 創建本地倉庫二&#xff09;配置本地倉庫三&#xff09;認識工作區、暫存區、版本庫四&#xff09;添加文件五&#xff09;查看.git文件六&#xff09;修改文…

基于docker部署的Selenium Grid分布式自動化測試

01、什么是Selenium Grid Selenium Grid是Selenium套件的一部分&#xff0c;它專門用于并行運行多個測試用例在不同的瀏覽器、操作系統和機器上。 Selenium Grid有兩個版本——老版本Grid 1和新版本Grid 2。我們只對新版本做介紹&#xff0c;因為Selenium團隊已經逐漸遺棄老版…

docker容器管理

創建容器&#xff1a; docker run --name 容器名 -d -p 端口1:端口2 –name :是啟動容器時&#xff0c;給容器定義的名稱&#xff0c;不使用該參數時&#xff0c;容器啟動成功之后&#xff0c;會生成隨機名稱 -d &#xff1a;代表容器處于后臺yunx -p &#xff1a;指定容器的端…

第一次參加計算機會議報告注意事項以及心得

計算機會議參會報告 注意事項參會前參會中參會后 參會心得 注意事項 接下來的會議注意事項分為&#xff1a;&#xff08;1&#xff09;參會前&#xff0c;&#xff08;2&#xff09;參會中&#xff0c;&#xff08;3&#xff09;參會后 參會前 參會前&#xff0c;一般被邀請…

實時安全分析監控加強網絡安全

網絡犯罪分子只需幾分鐘&#xff0c;有時甚至幾秒鐘即可泄露敏感數據。但是&#xff0c;IT 團隊可能無法在數周內發現這些違規行為。通常&#xff0c;這些違規行為是由外部方或客戶發現的&#xff0c;到那時為時已晚。隨著網絡漏洞的激增&#xff0c;對安全分析的需求空前高漲。…

【C# Programming】C#第一課(自己學習的筆記)

目錄 一、C# 介紹 1.1 托管代碼(Manage Code ) &#xff1a; 1.2 基礎類型庫 (Base Class Library)&#xff1a; 1.3 程序集(Assembly)&#xff1a; 1.4 .NET 框架&#xff1a; 1.5 公共中間語言(Common Intermediate Language)&#xff0c;簡稱 IL。 1.6 C#編譯器將源代…

實戰:工作中對并發問題的處理 | 京東物流技術團隊

1. 問題背景 問題發生在快遞分揀的流程中&#xff0c;我盡可能將業務背景簡化&#xff0c;讓大家只關注并發問題本身。 分揀業務針對每個快遞包裹都會生成一個任務&#xff0c;我們稱它為 task。task 中有兩個字段需要關注&#xff0c;一個是分揀中發生的異常&#xff08;exp…

DIP: Spectral Bias of DIP 頻譜偏置解釋DIP

On Measuring and Controlling the Spectral Bias of the Deep Image Prior 文章目錄 On Measuring and Controlling the Spectral Bias of the Deep Image Prior1. 方法原理1.1 動機1.2 相關概念1.3 方法原理頻帶一致度量與網絡退化譜偏移和網絡結構的關系Lipschitz-controlle…

Linux常規操作命令

日升時奮斗&#xff0c;日落時自省 目錄 1、vim 1.1、工作模式 1.2、末行模式操作相關命令 1.2.1、保存退出操作 1.2.2、查找替換 1.3、輸入模式操作相關命令 1.3.1、移動相關命令 1.3.2、刪除和剪切命令 1.3.3、復制操作 1.3.4、撤銷 2、head 3、tail 4、ps 5、…

數據結構算法--2 冒泡排序,選擇排序,插入排序

基礎排序算法 冒泡排序 思想就是將相鄰元素兩兩比較&#xff0c;當一個元素大于右側相鄰元素時&#xff0c;交換他們的位置&#xff0c;小于右側元素時&#xff0c;位置不變&#xff0c;最終序列中的最大元素&#xff0c;像氣泡一樣&#xff0c;到了最右側。 這時冒泡排序第一…

linux Socket簡單編程實例

服務端 網絡編程中服務端接受連接的套接字創建過程如下: 1.調用socket函數創建套接字 2.調用bind函數分配IP地址和端口號 3.調用listen函數轉為可接收請求狀態 4.調用accept函數受理連接請求 #include <stdio.h> #include <stdlib.h> #include <sys/types.h>…