io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1

今天写了个ping/pong的服务器和客户端玩

但是出现了以上错误

ReferenceCount(引用计数)错误,看了很久,发现每一次发送第二条消息就会报这个错误

发现第一条消息和第二条消息一样的(引用的同一个地址)

后面想到netty好像有个引用计数的东西

后面改了之后就好了,代码如下

 static class EchoClientHandler extends ChannelInboundHandlerAdapter {
        private final ByteBuf firstMessage;
         * Creates a client-side handler.
        public EchoClientHandler() {
            firstMessage = Unpooled.buffer(EchoClient.SIZE);
            firstMessage.writeBytes("ping".getBytes());
        @Override
        public void channelActive(ChannelHandlerContext ctx) {
            ctx.writeAndFlush(firstMessage);
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) {
            ByteBuf in = (ByteBuf) msg;
            while (in.isReadable()) {
                System.out.print((char) in.readByte());
                System.out.flush();
            System.out.println();
            //之前是ctx.wirte(firstMessage)导致了错误
            ByteBuf pong = Unpooled.buffer(EchoClient.SIZE);
            pong.writeBytes("ping".getBytes());
            ctx.write(pong);
				在netty4中,对象的生命周期由引用计数器控制,ByteBuf就是如此,每个对象的初始化引用计数加1,调用一次release方法,引用计数器会减1,当尝试访问计数器为0时,对象时,会抛出Illega...
											来自:	 飞奔的小土豆@1024
				转载自:https://emacsist.github.io/2018/04/28/netty%E4%B8%AD%E5%B8%B8%E8%A7%81%E7%9A%84illegalreferencec...
											来自:	 lizhengyu891231的博客
				运行时报错 io.netty.util.IllegalReferenceCountException: refCnt: 0	at io.netty.buffer.AbstractByteBuf.ens...
											来自:	 潘建南的博客
			求助,在使用netty5.0的时候遇到的这个问题 io.netty.util.IllegalReferenceCountException: refCnt: 0 @Override public vo
			代码运行到ByteBuf in = (ByteBuf) msg;
byte[] req = new byte[in.readableBytes()];
in.readBytes(req);
就会报错,哪位大神能解决?
public class ZhiNengKaiGuanServerHandler extends ChannelInboundHandlerAdapter {
	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		// TODO Auto-generated method stub
		super.channelActive(ctx);
		//与服务端建立连接后
		System.out.println("链接成功");
	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) 
			throws Exception {
		// TODO Auto-generated method stub
		super.channelRead(ctx, msg);
		System.out.println("server channelRead..");
		System.out.println("recive data:"+msg);
		ByteBuf in = (ByteBuf) msg;
		//in.retain();
		byte[] req = new byte[in.readableBytes()];
		in.readBytes(req);
		//String resultStr = new String(req);
        //System.out.println("Client said:" + resultStr);  
        // 释放资源,这行很关键  
        //in.release();  
		//String str=new String(req,"UTF-8");
		System.out.print("Receive data: { ");
	    for (int i = 0; i <req.length ; i++) {
	        String dhs = "00" + Integer.toHexString(req[i] & 0xFF);
	        System.out.print(dhs.substring(dhs.length() - 2, dhs.length())
	        .toUpperCase() + 
	        " ");
	    System.out.println(" } ");
	    String ser="hellow ,I'm Server";
	    ctx.write(ser);
	@Override
	public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
		// TODO Auto-generated method stub
		super.channelReadComplete(ctx);
		 System.out.println("server channelReadComplete..");
	     ctx.flush();//刷新后才将数据发出到SocketChannel
	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
			throws Exception {
		// TODO Auto-generated method stub
		super.exceptionCaught(ctx, cause);
		 System.out.println("server exceptionCaught..");
		 cause.printStackTrace();
	        ctx.close();
	public class ZhiNengKaiGuanServer {
	 private int port;
	 public ZhiNengKaiGuanServer(int port) {
	     this.port = port;
	 public void run() throws Exception {
	    	// 服务器线程组 用于网络事件的处理 一个用于服务器接收客户端的连接
			// 另一个线程组用于处理SocketChannel的网络读写
	        EventLoopGroup bossGroup = new NioEventLoopGroup(); // (1)
	        EventLoopGroup workerGroup = new NioEventLoopGroup();
	        try {
	        	// NIO服务器端的辅助启动类 降低服务器开发难度
	            ServerBootstrap b = new ServerBootstrap(); // (2)
	            b.group(bossGroup, workerGroup)
	             .channel(NioServerSocketChannel.class) // (3) 类似NIO中serverSocketChannel
	             .childHandler(new ChannelInitializer<SocketChannel>() { // (4)
	                 @Override
	                 public void initChannel(SocketChannel ch) throws Exception {
	                	 ch.pipeline().addLast("encoder", new ObjectEncoder());  
	                	 //ch.pipeline().addLast("decoder", new ObjectDecoder(Integer.MAX_VALUE, ClassResolvers.cacheDisabled(null))); 
	                	 //ch.pipeline().addLast("decoder", new StringEncoder());
	                	 //ch.pipeline().addLast("frameDecoder", new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4));  
	                	 //ch.pipeline().addLast("frameEncoder", new LengthFieldPrepender(4));  
	                	 // 自己的逻辑Handler
	                	 ch.pipeline().addLast(new ZhiNengKaiGuanServerHandler());
	             .option(ChannelOption.SO_BACKLOG, 1024)          // (5)
	             .childOption(ChannelOption.SO_KEEPALIVE, true); // (6)// 最后绑定I/O事件的处理类
	            // 服务器绑定端口监听
	            ChannelFuture f = b.bind(port).sync(); // (7)
	         // 监听服务器关闭监听
	            f.channel().closeFuture().sync();
	        } finally {
	        	// 优雅退出 释放线程池资源
				bossGroup.shutdownGracefully();
				workerGroup.shutdownGracefully();
				System.out.println("服务器优雅的释放了线程资源...");
	 public static void main(String[] args) throws Exception {
	        int port = 9000;
	        if (args != null && args.length > 0) {
	            try {
	                port = Integer.valueOf(args[0]);
	            } catch (NumberFormatException e) {
	        new ZhiNengKaiGuanServer(9527).run();
public class ZhiNengKaiGuanCommuccationConnector {
	// 配置客户端NIO线程组
	EventLoopGroup group = new NioEventLoopGroup();
	private ZhiNengKaiGuan zhiNengKaiGuan;
	public ZhiNengKaiGuanCommuccationConnector(ZhiNengKaiGuan zhiNengKaiGuan){
		 this.zhiNengKaiGuan=zhiNengKaiGuan;
	public ZhiNengKaiGuan getZhiNengKaiGuan() {
		return zhiNengKaiGuan;
	public void setZhiNengKaiGuan(ZhiNengKaiGuan zhiNengKaiGuan) {
		this.zhiNengKaiGuan = zhiNengKaiGuan;
	public void connect(final byte[] req) throws Exception {
		int port=zhiNengKaiGuan.getPort();
		String IP=zhiNengKaiGuan.getIp();
		System.out.println("this zhinengchazuo ip :" + this.zhiNengKaiGuan.getIp() + 
		        " port:" + this.zhiNengKaiGuan.getPort());
		      System.out.print("Send Command: { ");
		      for (int i = 0; i < req.length; i++) {
		        String dhs = "00" + 
		          Integer.toHexString(req[i] & 0xFF);
		        System.out.print(dhs.substring(dhs.length() - 2, 
		          dhs.length()).toUpperCase() + 
		          " ");
		      System.out.println(" } ");
		//配置客户端NIO线程组
		EventLoopGroup group = new NioEventLoopGroup();
		try {
			//客户端辅助启动类 对客户端配置
			Bootstrap b = new Bootstrap(); // (1)
            b.group(group); // (2)
            b.channel(NioSocketChannel.class); // (3)
            b.option(ChannelOption.SO_KEEPALIVE, true); // (4)
            b.handler(new ChannelInitializer<SocketChannel>() {
                @Override
                public void initChannel(SocketChannel ch) throws Exception {
                	ch.pipeline().addLast("encoder", new ObjectEncoder());  
                	ch.pipeline().addLast("decoder", new ObjectDecoder(Integer.MAX_VALUE, ClassResolvers.cacheDisabled(null)));
                	ch.pipeline().addLast(new ZhiNengKaiGuanCommuncationHander(req));
			//异步链接服务器 同步等待链接成功
			ChannelFuture f = b.connect(IP, port).sync();
			//等待链接关闭
			f.channel().closeFuture().sync();
		} finally {
			group.shutdownGracefully();
			System.out.println("客户端优雅的释放了线程资源...");
public class ZhiNengKaiGuanCommuncationHander extends  ChannelInboundHandlerAdapter {
	private static final Logger logger=Logger.getLogger(ZhiNengKaiGuanCommuncationHander.class.getName());
	private  ByteBuf sendMessage;
	public ZhiNengKaiGuanCommuncationHander(byte[] reqs){
		sendMessage=Unpooled.buffer(reqs.length);
		sendMessage.writeBytes(reqs);
	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		System.out.println(sendMessage);
		ctx.writeAndFlush(sendMessage);
		System.out.println("客户端active");
	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg)
			throws Exception {
		System.out.println("客户端收到服务器响应数据");
		/*ByteBuf m = (ByteBuf) msg; // (1)
		try {
	        long currentTimeMillis = (m.readUnsignedInt() - 2208988800L) * 1000L;
	        System.out.println(new Date(currentTimeMillis));
	        byte[] req=new byte[m.readableBytes()];
	        CommonUtil.remsg=req;
	        m.readBytes(req);
	    	String body=new String(req,"UTF-8");
	    	System.out.println("Now is:"+body);
	        ctx.close();
	   } finally {
	         m.release();
	@Override
	public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
		ctx.flush();
		System.out.println("客户端收到服务器响应数据处理完成");
	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
			throws Exception {
		logger.warning("Unexpected exception from downstream:"+cause.getMessage());
		ctx.close();
		System.out.println("客户端异常退出");
public class Test2 {
	public static void main(String[] args) {
		ZhiNengKaiGuan s=new ZhiNengKaiGuan("127.0.1.1", 9527);
		KaiGuanCmd j=new KaiGuanCmd(s);
		j.query();
				上文介绍了如何应用Netty开发自定义通讯协议,本文在此基础上进一步深化,研究如何同时支持不同的通讯协议。此处所谓的通讯协议,指的是把Netty通讯管道中的二进制流转换为对象、把对象转换成二进制流的过...
											来自:	 路漫漫其修远兮,吾将上下而求索
				Nettyhandler的exceptionCaught只会catchinboundhandler的exception,outboundexceptions需要在writeAndFlush方法里加上l...
											来自:	 静__嘘的博客
				在下面代码中public class EchoServerHandler extends SimpleChannelInboundHandler {    @Override    public vo...
											来自:	 lpfasd123的博客
				io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1at io.netty.buffer.AbstractRefe...
				1. io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1io.netty.util.IllegalReferen...
											来自:	 masterShaw的博客
			using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Secu
			client把服务强制关掉(如停止服务或杀进程),server端会异常 java.io.IOException: 远程主机强迫关闭了一个现有的连接。 at sun.nio.ch.SocketDispa
			netty4 io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1
网上也看了,是relase了,造成实例被收回。这个要怎么处理?前提这是tcp长连接,怎么也会被收回???
				首先,我们再看一下 ByteBuf 的类设计图,从中更进一步了解ByteBuf。ByteBuf 继承自 ReferenceCounted,引用计数,也就是说 ByteBuf 的内存回收使用的是引用计数...
											来自:	 prestigeding的博客
				本文主要包括以下内容:   1)ByteBuf的三种类型:heapBuffer(堆缓冲区)、directBuffer(直接缓冲区)以及Composite Buffer(复合缓冲区)。    2)Byt...
											来自:	 惜暮
				我们这一篇文章要使用的用户代码如下:    public static void main(String[] args) {        PooledByteBufAllocator allocat...
											来自:	 翻身咸鱼的博客
				从Netty 4起,对象的生命周期由它们的引用计数来管理,因此,一旦对象不再被引用后,Netty 会将它(或它共享的资源)归还到对象池(或对象分配器)。在垃圾回收和引用队列不能保证这么有效、实时的不可...
											来自:	 浩子的博客
				ByteBuf ByteBuf是Netty提供的代替jdk的ByteBuffer的一个容器,首先看一下他的具体用法:public class ByteBufTest0 {    public stat...
											来自:	 wzq6578702的专栏
				1. Netty - ByteBuf (3)1.3 ByteBuf相关实现源码相关类继承关系 其中,我们从AbstractByteBuf和他的子类开始分析,其他的多为衍生工具类。1.3.1. Abst...
											来自:	 iteye_20566的博客
				1. 背景\\1.1. 惊人的性能数据\\最近一个圈内朋友通过私信告诉我,通过使用Netty4 + Thrift压缩二进制编解码技术,他们实现了10W TPS(1K的复杂POJO对象)的跨节点远程服务...
											来自:	 cpongo4
			公司的一个项目用netty跟客户端交互,刚刚启动项目一切正常 但是过了一两天就开始报下面的错误 io.netty.util.internal.OutOfDirectMemoryError: faile
				netty使用基于thread-local的轻量级对象池Recycler对ChannelOutboundBuffer进行回收。当ChannelOutboundBuffer第一次被实例化且使用完毕后,会...
											来自:	 流子的专栏
				在做cxf+spring+mybatis整合的时候发现logger日志无法正常输出,即使配置为debug级别也不会输出日志,自己无意中用了下spring的日志文件 slf4j-api-1.7.5.ja...
											来自:	 口袋里的小龙的专栏
				被引用计数包含的对象,能够显示的被垃圾回收。当初始化的时候,计数为1。retain()方法能够增加计数,release() 方法能够减少计数,如果计数被减少到0则对象会被显示回收,再次访问被回收的这些...
											来自:	 huiGod的博客
				原文出处:http://netty.io/wiki/reference-counted-objects.html原文地址可能有变,且内容可能发生变化。如果转载请注明出处,谢谢合作^_^。 自从Nett...
											来自:	 xcc的博客
			private void button1_Click(object sender, EventArgs e) { string strName = tbName.Text; string strPwd
			this.Root.SelectNodes(xpath).Cast<XmlNode>().ToList<XmlNode>().ForEach((Action<XmlNode>) (a => (a.Va
				官方的 user-guide-for-5.x 中第一个例子 [ Writing a Discard Server ]就是最简单的例子源代码自带的全部的example代码都可以在官方下载的压缩文件 ne...
											来自:	 UPUP
				参考文献https://www.jianshu.com/p/b9f3f6a16911概述如果没有netty,远古时代我们会使用java.net + java.io,在近代,我们会使用java.nio,...
											来自:	 define_us的专栏
				学下下网络编程中常用的两个Buffer,ByteBuffer和ByteBuf,接下来会分析两者的细节及区别。先来看看ByteBuffer一.ByteBuffer  ByteBuffer是JDK NIO...
				点击上面↑「爱开发」关注我们每晚10点,捕获技术思考和创业资源洞察什么是ThreadLocalThreadLocal是一个本地线程副本变量工具类,各个线程都拥有一份线程私......
											来自:	 爱开发
				一、准备工作u盘,电脑一台,win10原版镜像(msdn官网)二、下载wepe工具箱极力推荐微pe(微pe官方下载)下载64位的win10 pe,使用工具箱制作启动U盘打开软件,选择安装到U盘(按照操...
											来自:	 weixin_41964258的博客
				由于我之前一直强调数据结构以及算法学习的重要性,所以就有一些读者经常问我,数据结构与算法应该要学习到哪个程度呢?,说实话,这个问题我不知道要怎么回答你,主要取决于你想学习到哪些程度,不过针对这个问题,...
											来自:	 帅地
在可视化化程序设计的今天,借助于集成开发环境可以很快地生成程序,程序设计不再是计算机专业人员的专利。很多人认为,只要掌握几种开发工具就可以成为编程高手,其实,这是一种误解。要想成为一个专业的...
				​	进程通信是指进程之间的信息交换。这里需要和进程同步做一下区分,进程同步控制多个进程按一定顺序执行,进程通信是一种手段,而进程同步是目标。从某方面来讲,进程通信可以解决进程同步问题。
​	首先回顾下...
				我清晰的记得,刚买的macbook pro回到家,开机后第一件事情,就是上了淘宝网,花了500元钱,找了一个上门维修电脑的师傅,上门给我装了一个windows系统。。。。。。
表砍我。。。
当时买ma...
				双11不光是购物狂欢节,更是对技术的一次“大考”,对于阿里巴巴企业内部运营的基础保障技术而言,亦是如此。
回溯双11历史,这背后也经历过“小米加步枪”的阶段:作战室从随处是网线,交换机放地上的“一地...
				小编是一个理科生,不善长说一些废话。简单介绍下原理然后直接上代码。
使用的工具(Python+pycharm2019.3+selenium+xpath+chromedriver)其中要使用pycha...
				CPU对每个程序员来说,是个既熟悉又陌生的东西?
如果你只知道CPU是中央处理器的话,那可能对你并没有什么用,那么作为程序员的我们,必须要搞懂的就是CPU这家伙是如何运行的,尤其要搞懂它里面的寄存器是...
				2020年1月17日,国家统计局发布了2019年国民经济报告,报告中指出我国人口突破14亿。
猪哥的朋友圈被14亿人口刷屏,但是很多人并没有看到我国复杂的人口问题:老龄化、男女比例失衡、生育率下降、人...
				相信大家都已经收到国务院延长春节假期的消息,接下来,在家远程办公可能将会持续一段时间。
但是问题来了。远程办公不是人在电脑前就当坐班了,相反,对于沟通效率,文件协作,以及信息安全都有着极高的要求。有...
				其实,这篇文章,我应该早点写的,毕竟现在已经2月份了。不过一些其它原因,或者是我的惰性、还有一些迷茫的念头,让自己迟迟没有试着写一点东西,记录下,或者说是总结下自己前3年的工作上的经历、学习的过程。
				所有群全部吵翻天,朋友圈全部沦陷,公众号疯狂转发。这两周没怎么发原创,只发新闻,可能有人注意到了。我不是懒,是文章写了却没发,因为大家的关注力始终在这次的疫情上面,发了也没人看。当然,我......
				Java Magazine上面有一个专门坑人的面试题系列: https://blogs.oracle.com/javamagazine/quiz-2。
这些问题的设计宗旨,主要是测试面试者对Java语...
				By 超神经场景描述:昨天 2 月 3 日,是大部分城市号召远程工作的第一天,全国有接近 2 亿人在家开始远程办公,钉钉上也有超过 1000 万家企业活跃起来。关键词:十一出行 人脸......
				Java基础知识点梳理
虽然已经在实际工作中经常与java打交道,但是一直没系统地对java这门语言进行梳理和总结,掌握的知识也比较零散。恰好利用这段时间重新认识下java,并对一些常见的语法...
				哇说起B站,在小九眼里就是宝藏般的存在,放年假宅在家时一天刷6、7个小时不在话下,更别提今年的跨年晚会,我简直是跪着看完的!!
最早大家聚在在B站是为了追番,再后来我在上面刷欧美新歌和漂亮小姐姐的舞蹈...
				蒙特卡罗方法,也称统计模拟方法,是1940年代中期由于科学技术的发展和电子计算机的发明,而提出的一种以概率统计理论为指导的数值计算方法。是指使用随机数(或更常见的伪随机数)来解决很多计算问题的方法
				你好呀,我是沉默王二,一个和黄家驹一样身高,和刘德华一样颜值的程序员。虽然已经写了十多年的 Java 代码,但仍然觉得自己是个菜鸟(请允许我惭愧一下)。
在一个月黑风高的夜晚,我思前想后,觉得再也不能...
				Web播放器解决了在手机浏览器和PC浏览器上播放音视频数据的问题,让视音频内容可以不依赖用户安装App,就能进行播放以及在社交平台进行传播。在视频业务大数据平台中,播放数据的统计分析非常重要,所以We...
				Spring1.Spring是什么?有什么好处?2.IOC是什么?有什么好处?具体过程?3.DI是什么?4.IOC和DI的关系?5.bean标签的属性有哪些?6.IOC创建对象有哪几种方式?7.Spr...
				作者| Just出品|CSDN(CSDNnews)紧急驰援疫区,AI医生也出动了。截止到2月6日,随着新冠病毒肺炎疫情的不断发展,全国累计已有31161例确诊病例,26359例疑......
				本文知识点较多,篇幅较长,请耐心学习
MySQL已经成为时下关系型数据库产品的中坚力量,备受互联网大厂的青睐,出门面试想进BAT,想拿高工资,不会点MySQL优化知识,拿offer的成功率会大大下降...
利用HTML5,css,js实现爱心树 以及 纪念日期的功能 网页有播放音乐功能 以及打字倾诉感情的画面,非常适合情人节送给女朋友
具体的HTML代码
具体只要修改代码里面的男某某和女某某 文字...
				4 容器类型
容器深层含义自己不知道,但是就表面意思。我自己理解的容器就是容器。他就是一个可以装“东西”的罐子啥的。不同的“罐子”可以装的“东西”不同,就像酒杯装酒,茶杯装茶,水缸装水。酒杯、茶杯、水...