我正在使用netty 4.0.26.Final来开发代理服务器(基于HexDumpProxy示例),它可以缓存对某种类型请求的响应。因此,当收到缓存其响应的请求时,它将返回缓存的响应,而不会将管道传递给主机。
现在我有逻辑运行没有错误但是当我激活ResourceLeakDetector到偏执级别时,由于存储在缓存中的响应中的ByteBuf,我得到资源泄漏错误(我认为)。
以下是HexDumpProxyFrontendHandler之前管道中处理程序位置的代码。插入缓存中的ResultMessage实现了ByteBufHolder。
public class CacheHandler extends ChannelDuplexHandler {
private final ConcurrentHashMap<String, ResultMessage> cache;
private String cacheKey;
public CacheHandler(ConcurrentHashMap<String, ResultMessage> cache) {
this.cache = cache;
}
@Override
public void channelRead(final ChannelHandlerContext ctx, Object msg) throws Exception {
// Check if the message is an instance of Message, if not we can not cache its value
if (msg instanceof Message) {
Message myMsg = (Message) msg;
// Check if there is a cache key for this Message,
// again if no cache key is available the message is not suitable for caching
cacheKey = myMsg.getCacheKey();
if (cacheKey != null) {
ResultMessage resultMsg = cache.get(cacheKey);
if (resultMsg != null) {
// Response is actually cached and returned directly
ctx.writeAndFlush(resultMsg.retain()).addListener(ChannelFutureListener.CLOSE);
} else {
// Response is not cached yet, it is necessary to follow the pipeline to the host
ctx.fireChannelRead(msg);
}
} else {
ctx.fireChannelRead(msg);
}
} else {
ctx.fireChannelRead(msg);
}
}
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
// Check if it is a response to a request suitable for caching
if (cacheKey != null && msg instanceof ResultMessage) {
ResultMessage resultMsg = (ResultMessage) msg;
cache.put(cacheKey, resultMsg.retain());
}
ctx.write(msg, promise);
}
}
这是记录的错误
[nioEventLoopGroup-3-4] ERROR io.netty.util.ResourceLeakDetector - LEAK: ByteBuf.release() was not called before it's garbage-collected. See http://netty.io/wiki/reference-counted-objects.html for more information.
任何有助于避免此资源泄漏的帮助都将受到高度赞赏。
答案 0 :(得分:1)
我已经意识到在返回缓存的邮件之前,我没有发布在频道中收到的原始邮件。因此解决方案是在返回之前释放它。
...
// Response is actually cached and returned directly
myMsg.release();
ctx.writeAndFlush(resultMsg.retain()).addListener(ChannelFutureListener.CLOSE);
...