Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding how Netty memory-leak would happen if release is not called

I have read various StackOverFlow QAs and external links and blogs about memory leak in Netty, starting from ReferenceCountedObjects and ManuallyHandlingReferenceCounting, BufferOwnership, TwitterBlog, ChannelOutboundHandlerFlushedBufferLeak, and other links that stem from these pages.

I understand that if the application doesn't release the resource once it is done with it, the actual memory itself will be GCed, but still Netty's pool size will increase and cause memory leak.

Couple of quotes from the links above explaining this are "even if the buffers themselves are garbage collected, the internal data structures used to store the pool will not.", "PooledByteBufAllocator uses the Recycler as well for “pooling” the ByteBuf container (not the memory it refer to itself tho)."

Can someone please explain a bit more about how this could happen? If ByteBuf is a container which is referring to a memory, how can the memory be collected while the ByteBuf is still in Netty memory pool? I visualize that Netty maintains a pool of ByteBuf(s) and reuse the memory it refers to when its reference count becomes 0. With this assumption, I can't understand how the memory itself can be GCed if the ByteBuf is still present in Netty's pool?

Can someone please clarify it in simple terms?

like image 237
Amudhan Avatar asked Mar 27 '18 12:03

Amudhan


1 Answers

So let me try to clarify things here.... basically Netty uses separate pools for the memory itself and for the container around it.

The container is ByteBuf here. Netty is pooling the ByteBuf in a Recycler (which is basically an object pool). The important thing to note here is that it "nulls" out the reference to the actual underlying memory (aka storage) that will be used to actually store the bytes.

The bytes itself (that will be exposed via the ByteBuf container) exist in a different pool. This pool only holds the backing storage for the ByteBuf but not the ByteBuf itself. The backing storage may be on-heap (byte[]) or off-heap (native/direct memory).

So both of these can be be the cause of a memory leak in theory. While in practice most of the memory leaks are caused by not calling ByteBuf.release() which leaks the backing memory.

like image 96
Norman Maurer Avatar answered Nov 24 '22 12:11

Norman Maurer