有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

ByteToMessageDecoder类中的java内存泄漏

我是内蒂的新手。我必须使用静态管道(因为项目经理更喜欢它)。这有点困难,因为我必须在同一条线上处理RTP和RTSP协议

虽然它几乎可以工作,但是内存泄漏。 我猜是我的分裂班的错。 此外,我认为错误可能是近旁路方法(因为netty的开发人员为了避免不定式循环,不允许将ByteBuf保持不变,这就是我必须创建旁路方法的原因。)

如果你有任何想法,请帮帮我!(提前感谢!)

这是我的代码:

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.MessageList;
import io.netty.handler.codec.ByteToMessageDecoder;
import java.util.ArrayList;
import java.util.List;

public class Splitter extends ByteToMessageDecoder {

    private ByteBuf bb = Unpooled.buffer();
    final RtspClientHandler rtspClientHandler;
    final RtpClientHandler rtpClientHandler;

    public Splitter(RtspClientHandler rtspClientHandler, RtpClientHandler rtpClientHandler) {
        this.rtspClientHandler = rtspClientHandler;
        this.rtpClientHandler = rtpClientHandler;
    }

    protected void bypass(ByteBuf in, MessageList<Object> out) {
        bb.writeBytes(in);
        in.discardReadBytes();
        bb.retain();
        out.add(bb);
    }

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, MessageList<Object> out) throws Exception {
        if (rtspClientHandler.getRTSPstate() == RtspClientHandler.RTSP_CLIENT_STATE.READY) {
            if (in.getByte(0) == 0x24 && in.readableBytes() > 4) {
                int lengthToRead = in.getUnsignedShort(2);
                if (in.readableBytes() >= (lengthToRead + 4)) {
                    in.skipBytes(4);
                    if (in.getByte(16) == 0x67 || in.getByte(16) == 0x68) {
                        final byte bytes[] = new byte[lengthToRead];
                        in.readBytes(bytes);
                        in.discardReadBytes();
                        SPSPPSbuffer spspps = new SPSPPSbuffer();
                        spspps.setSPSPPS(bytes);
                        out.add(spspps);

                    } else {
                        final byte packetArray[] = new byte[lengthToRead];// copy packet.
                        in.readBytes(packetArray);
                        in.discardReadBytes();
                        out.add(packetArray);
                    }
                }
            } else {
                bypass(in, out);
            }
        } else {
            bypass(in, out);
        }
    }
}

共 (1) 个答案

  1. # 1 楼答案

    看来我能解决它

    主要的事情是:我必须使用一个收集器ByteBuf,其中我收集来自网络的所有字节(我必须清除输入ByteBuf),因为有4种情况可能:

    • 字节数(在收集器中)小于RTP块大小

    • 字节数(在收集器中)等于RTP块大小

    • 字节数(在收集器中)大于RTP块大小

    • 收集器ByteBuf中有多个块

    以下是代码:

    import io.netty.buffer.ByteBuf;
    import io.netty.buffer.Unpooled;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.MessageList;
    import io.netty.handler.codec.ByteToMessageDecoder;
    
    public class Splitter extends ByteToMessageDecoder {
    
    private ByteBuf collector = Unpooled.buffer();
    final RtspClientHandler rtspClientHandler;
    final RtpClientHandler rtpClientHandler;
    
    public Splitter(RtspClientHandler rtspClientHandler, RtpClientHandler rtpClientHandler) {
        this.rtspClientHandler = rtspClientHandler;
        this.rtpClientHandler = rtpClientHandler;
    }
    
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, MessageList<Object> out) throws Exception {
        collector.writeBytes(in);
        in.discardReadBytes();
        in.clear();
        if (rtspClientHandler.getRTSPstate() != RtspClientHandler.RTSP_CLIENT_STATE.READY) {
            System.out.println("RTSP communication in progress");
            collector.retain();
            out.add(collector);
            return;
        }
        if (collector.readableBytes() > 0 && collector.getByte(0) != 0x24) {
            System.out.println("Clearing the Unpooled.buffer() (because it does not start with 0x24)");
            collector.readerIndex(collector.writerIndex());
            collector.discardReadBytes();
        }
        System.out.println("*****New bytes arrived");
        while (collector.readableBytes() > 0 && collector.getByte(0) == 0x24) {
            System.out.println("Length: " + collector.readableBytes());
            if (collector.readableBytes() > 4) {
                int lengthToRead = collector.getUnsignedShort(2);
                if (collector.readableBytes() >= (lengthToRead + 4)) {
                    collector.skipBytes(4);
                    if (collector.getByte(16) == 0x67 || collector.getByte(16) == 0x68) {
                        final byte bytes[] = new byte[lengthToRead];
                        collector.readBytes(bytes);
                        collector.discardReadBytes();
                        SPSPPSbuffer spspps = new SPSPPSbuffer();
                        spspps.setSPSPPS(bytes);
                        out.add(spspps);
    
                    } else {
                        final byte packetArray[] = new byte[lengthToRead];// copy packet.
                        collector.readBytes(packetArray);
                        collector.discardReadBytes();
                        out.add(packetArray);
                    }
                } else {
                    System.out.println("Not enough length, " + (lengthToRead + 4) + " byte should be required (together with 4 bytes header)");
                    return;
                }
            } else {
                System.out.println("Less than 5 bytes");
                return;
            }
        }
    }
    

    }