大佬,我的思路是这样的,用完后直接将缓冲区直接释放了
结果,遇到的问题是如果执行byteBuf.release();这个方法后,客户端居然收不到信息了,连续点多次才能偶尔收到一两次,如果把byteBuf.release();注释掉,客户端能正常收发消息,但是缓冲区就没被释放了,这样是不是会造成内存堆积呢?注释前后对比图如下:
求大佬指导下我的误区,膜拜!!!
大佬,我的思路是这样的,用完后直接将缓冲区直接释放了
你注释了release()
方法后,你看你打印的信息:freed,说明bytebuf已经释放了资源。你没必要自己去执行释放。netty的操作都是异步的。你执行了wirteAndFlush
。就立即返回,而不是等着消息发出去了方法才返回。这就可能导致一个问题:你执行了writeAndFlsuh
,底层还没来得及发送,你就把ByteBuf
给清空了。所以客户端偶尔收不到消息,。
K哥,图片你好像看反了 ,我注释了 release()
方法后,我打印的信息是(ridx:0,widx:73,cap:128)
如果执行`release() ’ ,才是freed,但是收不到,对于这种异步的怎么才知道消息完全发出去呢?然后去正常释放呢?
读操作才需要自己释放buffer。写不需要,netty应该会自动的处理。虽然我不是很确定,但是我看官方的demo都没有释放写出去的buffer。就算是你要释放,也应该把释放的代码写在writeAndFlush
的回调监听里面。不能直接写在后面。我等下研究研究。
还有。这种提问,尽量的把代码复制出来,少贴图。想帮助你的人可以直接复制你的代码到编辑器进行调试。
好的,我下次注意
/***
* 发送消息至客户端
*
* @param cmd
* 消息号
* @param msg
* 消息内容
*/
public void write(Short cmd, byte[] msg) {
// 在此使用堆外缓冲区是为了将数据更快速的写入内核中,如果使用堆缓冲区会多一次堆内存向内核进行内存拷贝,这样会降低性能。
ByteBuf byteBuf = PooledByteBufAllocator.DEFAULT.directBuffer(msg.length);
// 添加数据包头(4字节)
byteBuf.writeInt(-1234);
// 添加消息号(2字节)
byteBuf.writeShort(cmd);
// 添加消息长度(2字节)
byteBuf.writeShort(msg.length);
// 添加消息内容
byteBuf.writeBytes(msg);
// System.err.println("发送字节" + byteBuf.readableBytes());
System.err.println("发送前的缓冲区" + byteBuf);
this.ctx.channel().writeAndFlush(new BinaryWebSocketFrame(byteBuf));
// byteBuf.release();
System.err.println("发送后的缓冲区" + byteBuf);
}