当前位置: 首页 > 知识库问答 >
问题:

ReplayingDecoder中出现ResourceAkDetector异常。何时释放字节缓冲区?

胡景焕
2023-03-14

我在扩展ReplayingDecoder的DecodeEventHandler类中遇到ResourceAkDetector异常。我很难理解何时何地应该释放任何方法的bytbuf。我需要释放传递的字节Buf吗?我尝试释放header、eventBody和attachedData 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);
    }
}
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.readBytes()创建的每个ByteBuf(头、eventBody和attachedData)时,稍后在处理事件时会遇到问题。我调用nioBuffer()从ByteBuf创建一个ByteBuffer,释放原始ByteBuf似乎会影响ioBuffer()调用的ByteBuffer。根据文档,返回的缓冲区与bytebuf共享内容,这很可能意味着我还不能发布它。我是否需要保留每个字节Buf,然后在处理事件时释放?除非有别的办法,否则看起来是这样的。

共有1个答案

于嘉许
2023-03-14

您正在通过bytebuf.readbytes创建新的bytebuf,需要释放它们。

大小写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
 类似资料:
  • 我正在尝试正确地使用ByteBuffer和BigEndian字节顺序格式。。 我有几个字段,我试图把它存储在Cassandra数据库之前放在一个单一的ByteBuffer中。 我将要写入Cassandra的字节数组由三个字节数组组成,如下所述- 现在,我需要快速压缩attributeValue数据,然后再将其存储在Cassandra中- 现在,我将编写,和snappy压缩的一起组成一个单字节数组,

  • 我已经创建了一个解码器来处理客户端发送的字节。给你 并在客户端发送字节时抛出下一个错误 Io.netty.handler.codec.DecoderException:java.lang.IllegalArgumentException:MinimumReadableBytes:-603652096(预期:>=0)在io.netty.handler.codec.ReplayingDecoder.C

  • 问题内容: 由于它不在jvm heap&gc中,何时发布?还是一直保留到流程终止? 但是所有答案都是模糊的,没有一个明确的答案,是否有明确的答案?至少适用于 64位Linux 上的 Java 8 。 __ 问题答案: 不使用旧的Java终结器。相反,它使用内部API。它创建一个新线程并存储到每个创建的线程中(除了重复和切片指的是主缓冲区)。当变成 幻影可到达的 (也就是说,不再存在对字节缓冲区的强

  • 我试图通过扩展现有的Java程序来实现概念验证的内存感知调度功能。程序使用字节[]形式的缓冲区。就我而言,字节[]有问题,因为 他们是垃圾回收 它们是预先分配的,而不是懒惰地分配的(JVM在创建缓冲区时似乎会触及它分配的所有页面) 它们使JVM分配越来越多的内存,而这些内存并没有还给操作系统。 为了实现我的目标,我希望缓冲区能够被延迟分配内存(只有在写入时才分配页面),并且可以按需释放。这与C中的

  • 我正在尝试用Java编写RSA加密和解密类,用于客户端来回传递字符串的服务器。我为这些类编写了以下代码: 我有以下测试类代码: 然而,当我尝试运行测试类时,密钥生成和加密工作正常,但当我尝试解密时,会出现一个错误。错误是javax。加密。IllegalBlockSizeException:数据不能超过128字节,但我的数据肯定小于128字节。 我可以确认将公钥转换为字符串并返回相同的公钥。我也尝试

  • 使用Spring JPA Hibernate Ehcache。 我正在尝试在L2缓存(使用EhCache)中缓存Hibernate集合。 实体用@Cache(region=abc,strategy=READ_WRITE)注释 当我尝试使用具有相同配置的注释来注释@CACHE个LAZY/EAGER 加载的集合时,它会导致下面提到的异常: java.lang.ClassCastException:or