Netty Message RefCount

ByteBuf is always reference counted

To control the life cycle of a ByteBuf in a more predictable way, Netty does not rely on the garbage collector anymore but employs an explicit reference counter. Here's the basic rule:

  • When a buffer is allocated, its initial reference count is 1.
  • If the reference count of the buffer is decreased to 0, it is deallocated or returned to the pool it originated from.
  • The following attempts trigger an IllegalReferenceCountException:
    • Accessing a buffer whose reference count is 0,
    • Decreasing the reference count to a negative value, or
    • Increasing the reference count beyond Integer.MAX_VALUE.
  • Derived buffers (e.g. slices and duplicates) and swapped buffers (i.e. little endian buffers) share the reference count with the buffer it was derived from. Note the the reference count does not change when a derived buffer is created.

When a ByteBuf is used in a ChannelPipeline, there are additional rules you need to keep in mind:

  • Each inbound (a.k.a. upstream) handler in a pipeline has to release the received messages. Netty does not release them automatically for you.
    • Note that codec framework does release the messages automatically and a user has to increase the reference count if he or she wants to pass a message as-is to the next handler.
  • When an outbound (a.k.a. downstream) message reaches at the beginning of the pipeline, Netty will release it after writing it out.
Automatic buffer leak detection

Although reference counting is very powerful, it is also error-prone. To help a user find where he or she forgot to release the buffers, the leak detector logs the stack trace of the location where the leaked buffer was allocated automatically.

Because the leak detector relies on PhantomReference and obtaining a stack trace is a very expensive operation, it samples approximately 1% of allocations only. Therefore, it's a good idea to run the application for a reasonably long time to find all possible leaks.

Once all leaks are found and fixed. You can turn this feature off to remove its runtime overhead completely by specifying the -Dio.netty.noResourceLeakDetection JVM option.

要使用 Netty 搭建一个 Socket 服务器,可以按照以下步骤获取消息 ID: 1. 创建一个 ChannelInitializer 类,用于初始化 ChannelPipeline。在该类中,可以添加一个自定义的 ChannelHandler,用于处理接收到的消息。 2. 在自定义的 ChannelHandler 中,重写 channelRead(ChannelHandlerContext ctx, Object msg) 方法,用于处理接收到的消息。 3. 在 channelRead() 方法中,获取接收到的 ByteBuf 数据,并根据协议解析出消息头和消息体。 4. 从消息头中获取消息 ID,可以根据消息 ID 来判断接收到的消息类型。 下面是一个简单的示例代码: ``` public class SocketServerInitializer extends ChannelInitializer<SocketChannel> { @Override protected void initChannel(SocketChannel socketChannel) throws Exception { ChannelPipeline pipeline = socketChannel.pipeline(); pipeline.addLast(new SocketServerHandler()); } } public class SocketServerHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { ByteBuf buf = (ByteBuf) msg; // 解析消息头,获取消息 ID int messageId = buf.getInt(0); // 根据消息 ID 处理消息体 switch (messageId) { case 1: // 处理消息类型为 1 的消息 break; case 2: // 处理消息类型为 2 的消息 break; default: // 处理未知消息类型 break; } } } ``` 在这个示例代码中,我们使用了一个自定义的 SocketServerHandler 来处理接收到的消息,并从消息头中获取了消息 ID。你可以根据自己的实际需求来修改这个示例代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值