ReferenceCounted
In Netty, ReferenceCounted is implemented under reference counting mechanism.
When a ReferenceCounted object is created, the reference count starts with 1. Then each time this object is passed to another component, retain() should be called and after finishing using it, release() should be called. When the reference count gets to 0, it is dead and the memory will be reclaimed.
| |
Implementation Class
ByteBuf is the most common implementation of ReferenceCounted.
ByteBuf is a high-performance byte container (like java.nio.ByteBuffer). It can be assigned in direct memory. For example:
| |
Direct buffers can’t be controlled by Java GCs, so reference counting is used to manage their lifecycles. Java programmers have something more to do here.
Channel Handler
Extending ChannelInboundHandlerAdapter is a common way to develop a handler. This class just does the basic things, such as ctx.fireXxx(). We invoke ReferenceCounted#retain and ReferenceCounted#release ourselves when the msg is a ReferenceCounted object.
| |
SimpleChannelInboundHandler is a convenient class and it does more things for users. There is a template method pattern. Users usually override channelRead0(). But pay attention that it will call release() method for you.
| |
This method releases for ReferenceCounted objects. If msg is not a ReferenceCounted object, it does nothing.
| |
Summary
At first I have two misconceptions of Netty’s reference counting mechanism:
- No need to call
release()inSimpleChannelInboundHandler? – Someone else does it for you. release()is called for every inbound message? – No, there is type check.
After grasping these points I make my mind clearer when using all kinds of components of Netty together.
This is a less-seen scenario where Java users need to apply reference counting themselves.