Netty解码器内存消耗

时间:2016-03-21 14:26:11

标签: netty heap-memory

我使用Netty IO(4.0.29 Final)来解码来自TCP服务器的字节。在我的管道的第一个位置,我使用LengthFieldBasedFrameDecoder来分割帧中的字节(这个处理程序工作正常)。在我的管道的第二个位置,我实现了我自己的处理程序,扩展了Netty的ByteToMessageDecoder。

在这个自定义处理程序中,我想做几个动作:

  1. 将字节转换为十六进制表示以便记录 文本文件,
  2. 验证框架的校验和,
  3. 基于字节#14和#15聚合帧,它们分别代表段号和段总数(所以当段号等于段总计数时,我的缓冲区已完成,它可以发送到下一个处理程序)。

    private ByteBuf aggregate;
    private short lastSegmentId;
    
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in,
        List<Object> out) throws Exception
    {
        String hexDump = ByteBufUtil.hexDump(in);
        RecordingService.record(hexDump);
    
        in = in.order(ByteOrder.LITTLE_ENDIAN);
    
        byte segId = in.getByte(14);
        byte segCnt = in.getByte(15);
    
        int readableBytes = in.readableBytes();
    
        int sum = 0;
        for (int index = 0; index < readableBytes-2; index++)
        {
            short s = in.readUnsignedByte();
            sum += s;
        }
        int checksum = in.readUnsignedShort();
    
        if (sum == checksum)
        {
            //
            // Checksum correct
            //  
            if (segId == (lastSegmentId + 1))
            {
                lastSegmentId = segId;
                byte[] byteArray = new byte[readableBytes-18];
                in.getBytes(16, byteArray, 0, readableBytes-18);
                aggregate.writeBytes(byteArray);
    
                if (lastSegmentId == segCnt)
                {
                    aggregate.readerIndex(0);
                    out.add(aggregate.copy());
                    lastSegmentId = 0;
                    aggregate.clear();
                }
                else
                {
                    lastSegmentId = 0;
                    aggregate.clear();
                }
            }
            else
            {
                //
                // Checksum not correct
                //
            }
        }
    }
    
  4. 这个自定义处理程序可以正常工作,但它会及时消耗大量内存,几个小时后,我的程序中出现了“OutOfMemoryError:java heap space”。

    我使用Java VisualVM来监视我的程序,我发现名为“nioEventLoopGroup-2-1”的netty线程占用了大量内存。如果我评论十六进制转储和代码进行聚合,则内存消耗会大幅减少。

    Netty thread memory consumption

    Java heap space

    我认为我的代码导致了问题,但我找不到解决方案。

    你能帮我理解什么是错的吗?

    感谢。

0 个答案:

没有答案