Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ByteBuf.release() was not called before it's garbage-collected #930

Closed
zhouzq opened this issue Nov 24, 2018 · 4 comments
Closed

ByteBuf.release() was not called before it's garbage-collected #930

zhouzq opened this issue Nov 24, 2018 · 4 comments
Labels
type: feature A new feature
Milestone

Comments

@zhouzq
Copy link

zhouzq commented Nov 24, 2018

I am using Lettuce 5.1.2.RELEASE + Netty 4.1.28.Final and see the following error.

2018-11-24 10:23:06.710|[lettuce-epollEventLoop-10-24]|ERROR|[Slf4JLogger.java:171]|LEAK: ByteBuf.release() was not called before it's garbage-collected. See http://netty.io/wiki/reference-counted-objects.html for more information.
Recent access records:
Created at:
        io.netty.buffer.PooledByteBufAllocator.newDirectBuffer(PooledByteBufAllocator.java:331)
        io.netty.buffer.AbstractByteBufAllocator.directBuffer(AbstractByteBufAllocator.java:185)
        io.netty.buffer.AbstractByteBufAllocator.directBuffer(AbstractByteBufAllocator.java:176)
        io.netty.buffer.AbstractByteBufAllocator.buffer(AbstractByteBufAllocator.java:113)
        io.lettuce.core.protocol.CommandArgs$KeyArgument.encode(CommandArgs.java:656)
        io.lettuce.core.protocol.CommandArgs.encode(CommandArgs.java:346)
        io.lettuce.core.protocol.Command.encode(Command.java:119)
        io.lettuce.core.protocol.AsyncCommand.encode(AsyncCommand.java:185)
        io.lettuce.core.cluster.ClusterCommand.encode(ClusterCommand.java:92)
        io.lettuce.core.protocol.CommandEncoder.encode(CommandEncoder.java:90)
        io.lettuce.core.protocol.CommandEncoder.encode(CommandEncoder.java:75)
        io.netty.handler.codec.MessageToByteEncoder.write(MessageToByteEncoder.java:107)
        io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:738)
        io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:730)
        io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:816)
        io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:723)
        io.lettuce.core.protocol.CommandHandler.writeSingleCommand(CommandHandler.java:414)
        io.lettuce.core.protocol.CommandHandler.write(CommandHandler.java:345)
        io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:738)
        io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:730)
        io.netty.channel.AbstractChannelHandlerContext.access$1900(AbstractChannelHandlerContext.java:38)
        io.netty.channel.AbstractChannelHandlerContext$AbstractWriteTask.write(AbstractChannelHandlerContext.java:1081)
        io.netty.channel.AbstractChannelHandlerContext$WriteAndFlushTask.write(AbstractChannelHandlerContext.java:1128)
        io.netty.channel.AbstractChannelHandlerContext$AbstractWriteTask.run(AbstractChannelHandlerContext.java:1070)
        io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
        io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404)
        io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:322)
        io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)
        io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        java.lang.Thread.run(Thread.java:748)

It seems the leak is from the invoke command.

@stillerrr
Copy link

stillerrr commented Nov 24, 2018

I think we need add "try catch finally" in this place: io.lettuce.core.protocol.CommandArgs
image
if some exception happened before the release() method, the temp buffer would not be released.

for example: run mset() command and set a lot of key, it would take a long time, before the future callback, use the method completeExceptionally() throwing an exception, I think it would recurrent

@mp911de
Copy link
Collaborator

mp911de commented Nov 24, 2018

The attached stack trace originates from Lettuce 5.x, not the 4.x version. Thanks for reporting the issue.

@mp911de mp911de added the type: feature A new feature label Nov 24, 2018
@mp911de mp911de added this to the 5.1.3 milestone Nov 24, 2018
mp911de added a commit that referenced this issue Nov 24, 2018
Lettuce now makes sure to properly release temporary buffers after encoding keys and values. This avoids memory leaks caused by encoding errors.
mp911de added a commit that referenced this issue Nov 24, 2018
Lettuce now makes sure to properly release temporary buffers after encoding keys and values. This avoids memory leaks caused by encoding errors.
mp911de added a commit that referenced this issue Nov 24, 2018
Lettuce now makes sure to properly release temporary buffers after encoding keys and values. This avoids memory leaks caused by encoding errors.
mp911de added a commit that referenced this issue Nov 24, 2018
Lettuce now makes sure to properly release temporary buffers after encoding keys and values. This avoids memory leaks caused by encoding errors.
@mp911de
Copy link
Collaborator

mp911de commented Nov 24, 2018

The improvement is in place now.

@mp911de mp911de closed this as completed Nov 24, 2018
@zhouzq
Copy link
Author

zhouzq commented Nov 24, 2018

Thanks for your reply.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: feature A new feature
Projects
None yet
Development

No branches or pull requests

3 participants