netty: DnsNameResolver leaks memory on error

resolver.query() returns a future, which potentially can be in error state.

In that scenario a user cannot get hold of the DatagramDnsResponse to release it.

Netty version

4.1.7

Jan 25, 2017 10:40:36 AM io.netty.util.ResourceLeakDetector reportTracedLeak
SEVERE: LEAK: DnsMessage.release() was not called before it's garbage-collected. See http://netty.io/wiki/reference-counted-objects.html for more information.
Recent access records: 1
#1:
	Hint: 'DnsNameResolver$DnsResponseHandler#0' will handle the message from this point.
	io.netty.handler.codec.dns.AbstractDnsMessage.touch(AbstractDnsMessage.java:363)
	io.netty.handler.codec.dns.DefaultDnsResponse.touch(DefaultDnsResponse.java:161)
	io.netty.handler.codec.dns.DatagramDnsResponse.touch(DatagramDnsResponse.java:167)
	io.netty.handler.codec.dns.DatagramDnsResponse.touch(DatagramDnsResponse.java:27)
	io.netty.channel.DefaultChannelPipeline.touch(DefaultChannelPipeline.java:107)
	io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:346)
	io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:341)
	io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102)
	io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
	io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:349)
	io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:341)
	io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334)
	io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
	io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:349)
	io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:926)
	io.netty.channel.nio.AbstractNioMessageChannel$NioMessageUnsafe.read(AbstractNioMessageChannel.java:93)
	io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:642)
	io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:565)
	io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:479)
	io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:441)
	io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858)
	io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144)
	java.lang.Thread.run(Thread.java:745)
Created at:
	io.netty.util.ResourceLeakDetector.track(ResourceLeakDetector.java:219)
	io.netty.handler.codec.dns.AbstractDnsMessage.<init>(AbstractDnsMessage.java:44)
	io.netty.handler.codec.dns.DefaultDnsResponse.<init>(DefaultDnsResponse.java:61)
	io.netty.handler.codec.dns.DatagramDnsResponse.<init>(DatagramDnsResponse.java:70)
	io.netty.handler.codec.dns.DatagramDnsResponseDecoder.newResponse(DatagramDnsResponseDecoder.java:87)
	io.netty.handler.codec.dns.DatagramDnsResponseDecoder.decode(DatagramDnsResponseDecoder.java:57)
	io.netty.handler.codec.dns.DatagramDnsResponseDecoder.decode(DatagramDnsResponseDecoder.java:33)
	io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:88)
	io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
	io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:349)
	io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:341)
	io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334)
	io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
	io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:349)
	io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:926)
	io.netty.channel.nio.AbstractNioMessageChannel$NioMessageUnsafe.read(AbstractNioMessageChannel.java:93)
	io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:642)
	io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:565)
	io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:479)
	io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:441)
	io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858)
	io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144)
	java.lang.Thread.run(Thread.java:745)
Jan 25, 2017 10:40:37 AM io.netty.util.ResourceLeakDetector reportTracedLeak
SEVERE: LEAK: ByteBuf.release() was not called before it's garbage-collected. See http://netty.io/wiki/reference-counted-objects.html for more information.

I know the description is rough, i am trying to extract a reproducer out of my app, but maybe this is sufficient for somebody to go: oh yeah…

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 21 (21 by maintainers)

Commits related to this issue

Most upvoted comments

maybe something interesting for this (and potentially other native memory leak issues)

https://bugs.openjdk.java.net/browse/JDK-8164293

The Hotspot compiler leaks memory. it can be worked around by turning TieredCompilation off: -XX:-TieredCompilation