缓存响应时资源泄漏

时间:2015-03-20 10:37:38

标签: netty

我正在使用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.

任何有助于避免此资源泄漏的帮助都将受到高度赞赏。

1 个答案:

答案 0 :(得分:1)

我已经意识到在返回缓存的邮件之前,我没有发布在频道中收到的原始邮件。因此解决方案是在返回之前释放它。

  ...
  // Response is actually cached and returned directly
  myMsg.release();
  ctx.writeAndFlush(resultMsg.retain()).addListener(ChannelFutureListener.CLOSE);
  ...