2016-06-07 1 views
2

Я столкнулся с исключением ResourceLeakDetector в моем классе DecodeEventHandler, который расширяет ReplayingDecoder. Мне трудно понять, когда и где я должен выпустить любой из BytBuf метода. Должен ли я освободить прошедший ByteBuf? Я попытался освободить заголовок, eventBody и attachData ByteBuf, но это создало проблемы позже в моем коде. Код ...Исключение ResourceLeakDetector в ReplayingDecoder. Когда я могу освободить ByteBuf?

protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception 
{ 
    switch (state()) 
    { 
     case READ_HEADER: 
      ByteBuf header = byteBuf.readBytes(BaseEvent.EVENT_HEADER_SIZE); 
      newEvent = new BaseEvent(header.nioBuffer()); 
      checkpoint(EventDecoderState.READ_BODY); 
      // Fall through 

     case READ_BODY: 
      ByteBuf eventBody = byteBuf.readBytes(newEvent.getEventHeaderBodySize() - BaseEvent.EVENT_HEADER_SIZE); 
      newEvent.setEventBody(eventBody.nioBuffer()); 
      checkpoint(EventDecoderState.READ_ATTACHED_DATA); 
      // Fall through 

     case READ_ATTACHED_DATA: 
      ByteBuf attachedData = byteBuf.readBytes(newEvent.getAttachedDataSize()); 
      newEvent.clearAttachedData(); 
      newEvent.addAttachedData(attachedData.nioBuffer()); 
      list.add(newEvent); 
      checkpoint(EventDecoderState.READ_HEADER); 
    } 
} 

Способ начинается в строке 23. исключение I А. Прием ...

2016-06-07 13:30:49.783 [ERROR] (nioEventLoopGroup-7-1) 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. 
Recent access records: 2 
#2: 
    io.netty.buffer.AdvancedLeakAwareByteBuf.nioBuffer(AdvancedLeakAwareByteBuf.java:669) 
    com.oakgate.netty.DecodeEventHandler.decode(DecodeEventHandler.java:30) 
    io.netty.handler.codec.ReplayingDecoder.callDecode(ReplayingDecoder.java:376) 
    io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:245) 
    io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:83) 
    io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:154) 
    io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:354) 
    io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:145) 
    io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86) 
    io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:83) 
    io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:154) 
    io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:354) 
    io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:145) 
    io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:266) 
    io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:83) 
    io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:154) 
    io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:354) 
    io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:145) 
    io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:1078) 
    io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:117) 
    io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:527) 
    io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:484) 
    io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:398) 
    io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:370) 
    io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:742) 
    io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:145) 
    java.lang.Thread.run(Thread.java:745) 
#1: 
    io.netty.buffer.AdvancedLeakAwareByteBuf.writeBytes(AdvancedLeakAwareByteBuf.java:561) 
    io.netty.buffer.AbstractByteBuf.readBytes(AbstractByteBuf.java:790) 
    io.netty.handler.codec.ReplayingDecoderByteBuf.readBytes(ReplayingDecoderByteBuf.java:576) 
    com.oakgate.netty.DecodeEventHandler.decode(DecodeEventHandler.java:29) 
    io.netty.handler.codec.ReplayingDecoder.callDecode(ReplayingDecoder.java:376) 
    io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:245) 
    io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:83) 
    io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:154) 
    io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:354) 
    io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:145) 
    io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86) 
    io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:83) 
    io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:154) 
    io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:354) 
    io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:145) 
    io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:266) 
    io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:83) 
    io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:154) 
    io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:354) 
    io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:145) 
    io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:1078) 
    io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:117) 
    io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:527) 
    io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:484) 
    io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:398) 
    io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:370) 
    io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:742) 
    io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:145) 
    java.lang.Thread.run(Thread.java:745) 
Created at: 
    io.netty.buffer.PooledByteBufAllocator.newDirectBuffer(PooledByteBufAllocator.java:271) 
    io.netty.buffer.AbstractByteBufAllocator.directBuffer(AbstractByteBufAllocator.java:179) 
    io.netty.buffer.AbstractByteBufAllocator.buffer(AbstractByteBufAllocator.java:115) 
    io.netty.buffer.AbstractByteBuf.readBytes(AbstractByteBuf.java:789) 
    io.netty.handler.codec.ReplayingDecoderByteBuf.readBytes(ReplayingDecoderByteBuf.java:576) 
    com.oakgate.netty.DecodeEventHandler.decode(DecodeEventHandler.java:29) 
    io.netty.handler.codec.ReplayingDecoder.callDecode(ReplayingDecoder.java:376) 
    io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:245) 
    io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:83) 
    io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:154) 
    io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:354) 
    io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:145) 
    io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86) 
    io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:83) 
    io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:154) 
    io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:354) 
    io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:145) 
    io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:266) 
    io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:83) 
    io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:154) 
    io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:354) 
    io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:145) 
    io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:1078) 
    io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:117) 
    io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:527) 
    io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:484) 
    io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:398) 
    io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:370) 
    io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:742) 
    io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:145) 
    java.lang.Thread.run(Thread.java:745) 

Дополнительная информация

Когда я выпустить каждый ByteBuf созданный по вызову byteBuf.readBytes() (заголовок, eventBody и прикрепленные данные) У меня возникают проблемы позже при обработке события. Я вызываю nioBuffer(), чтобы создать ByteBuffer из ByteBuf, и кажется, что освобождение исходного ByteBuf влияет на ByteBuffer из вызова ioBuffer(). Согласно документам, возвращенный буфер разделяет контент с bytebuf, который, скорее всего, означает, что я пока не могу его освободить. Мне нужно сохранить каждый ByteBuf, а затем отпустить, когда событие обработано? Это выглядит так, если нет другого способа сделать это.

ответ

1

Вы создаете новые ByteBuf с помощью byteBuf.readBytes, их необходимо освободить.

Пример для вашего case READ_HEADER::

case READ_HEADER: 
    ByteBuf header = null; 
    try { 
     header = byteBuf.readBytes(BaseEvent.EVENT_HEADER_SIZE); 
     newEvent = new BaseEvent(header.nioBuffer()); 
     checkpoint(EventDecoderState.READ_BODY); 
    } finally { 
     if(header != null) 
      header.release(); 
    } 
    // Fall through 
+0

Спасибо за ответ. Я добавил дополнительную информацию, описывающую, что происходит, когда я реализую ваше предложение. –

Смежные вопросы