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.mzph.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…

大数据课程I3——Kafka的消息流与索引机制

文章作者邮箱:yugongshiye@sina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 掌握Kafka的消息流处理; ⚪ 掌握Kafka的索引机制; ⚪ 掌握Kafka的消息系统语义; 一、Kafka消息流处理 1. Producer 写入消息 流程说明: 1. producer 要向Kafka生产消息,需要先通过…

EditPlus连接Linux系统远程操作文件

EditPlus是一套功能强大的文本编辑器! 1.File ->FTP->FTP Settings; 2.Add->Description->FTP server->Username->Password->Subdirectory->Advanced Options 注意:这里的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开机联网跳过不了怎么办?Win11开机联网跳过不了解决方法 Win11开机联网跳过不了怎么办?Win11开机…

Unity框架学习--5 事件中心管理器

作用:访问其它脚本时,不直接访问,而是通过发送一条“命令”,让监听了这条“命令”的脚本自动执行对应的逻辑。 原理: 1、让脚本向事件中心添加事件,监听对应的“命令”。 2、发送“命令”,事件…

【Git】安装以及基本操作

目录 一、初识Git二、 在Linux底下安装Git一)centOS二)Ubuntu 三、 Git基本操作一) 创建本地仓库二)配置本地仓库三)认识工作区、暂存区、版本库四)添加文件五)查看.git文件六)修改文…

基于docker部署的Selenium Grid分布式自动化测试

01、什么是Selenium Grid Selenium Grid是Selenium套件的一部分,它专门用于并行运行多个测试用例在不同的浏览器、操作系统和机器上。 Selenium Grid有两个版本——老版本Grid 1和新版本Grid 2。我们只对新版本做介绍,因为Selenium团队已经逐渐遗弃老版…

docker容器管理

创建容器: docker run --name 容器名 -d -p 端口1:端口2 –name :是启动容器时,给容器定义的名称,不使用该参数时,容器启动成功之后,会生成随机名称 -d :代表容器处于后台yunx -p :指定容器的端…

实时安全分析监控加强网络安全

网络犯罪分子只需几分钟,有时甚至几秒钟即可泄露敏感数据。但是,IT 团队可能无法在数周内发现这些违规行为。通常,这些违规行为是由外部方或客户发现的,到那时为时已晚。随着网络漏洞的激增,对安全分析的需求空前高涨。…

【C# Programming】C#第一课(自己学习的笔记)

目录 一、C# 介绍 1.1 托管代码(Manage Code ) : 1.2 基础类型库 (Base Class Library): 1.3 程序集(Assembly): 1.4 .NET 框架: 1.5 公共中间语言(Common Intermediate Language),简称 IL。 1.6 C#编译器将源代…

实战:工作中对并发问题的处理 | 京东物流技术团队

1. 问题背景 问题发生在快递分拣的流程中,我尽可能将业务背景简化,让大家只关注并发问题本身。 分拣业务针对每个快递包裹都会生成一个任务,我们称它为 task。task 中有两个字段需要关注,一个是分拣中发生的异常(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常规操作命令

日升时奋斗,日落时自省 目录 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 冒泡排序,选择排序,插入排序

基础排序算法 冒泡排序 思想就是将相邻元素两两比较,当一个元素大于右侧相邻元素时,交换他们的位置,小于右侧元素时,位置不变,最终序列中的最大元素,像气泡一样,到了最右侧。 这时冒泡排序第一…

linux Socket简单编程实例

服务端 网络编程中服务端接受连接的套接字创建过程如下: 1.调用socket函数创建套接字 2.调用bind函数分配IP地址和端口号 3.调用listen函数转为可接收请求状态 4.调用accept函数受理连接请求 #include <stdio.h> #include <stdlib.h> #include <sys/types.h>…

STM32自带的DSP库的滤波初体验(一)

最近在弄STM32自带的DSP库里的滤波&#xff0c;记录一下&#xff1a; arm_fir_instance_q15 instance_q15_S; #define NUM_TAPS 16 //滤波系数的个数 #define BLOCK_SIZE 32 q15_t firStateF32[BLOCK_SIZE NUM_TAPS]; q15_t Fir_Coeff[NUM_TAPS] {-79, -136, 312, 6…

MongoDB 简介

什么是MongoDB ? MongoDB 是由C语言编写的&#xff0c;是一个基于分布式文件存储的开源数据库系统。 在高负载的情况下&#xff0c;添加更多的节点&#xff0c;可以保证服务器性能。 MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。 MongoDB 将数据存储为一个…

mqttfx连上OneNET生成token时的一大坑,报用户名或密码错误

整个流程如下连接&#xff1a; MQTT.fx和MQTTX 链接ONENET物联网开发平台避坑细节干货。 其中在生成token时&#xff0c;搞了半天在连接后都会报用户名密码错误 最后发现是格式问题&#xff0c;输入所有字符后一定要双击看是否可以全选中&#xff0c;可以全选中说明字符的格式…