JnetPcap:从离线文件读取非常慢

JnetPcap: reading from offline file very slow

我正在使用 jnetpcap v1.4r1425 构建一种自定义版本的 wireshark。我只想打开离线 pcap 文件并将它们显示在我的 tableview 中,除了速度之外效果很好。 我打开的文件大约有 100mb,有 700k 个包。

public ObservableList<Frame> readOfflineFiles1(int numFrames) {  
    ObservableList<Frame> frameData = FXCollections.observableArrayList();

    if (numFrames == 0){
        numFrames = Pcap.LOOP_INFINITE;
    }
    final StringBuilder errbuf = new StringBuilder();  

    final Pcap pcap = Pcap.openOffline(FileAddress, errbuf);  
    if (pcap == null) {  
        System.err.println(errbuf); // Error is stored in errbuf if any  
        return null;  
    } 


    JPacketHandler<StringBuilder> packetHandler =  new JPacketHandler<StringBuilder>() {
        public void nextPacket(JPacket packet, StringBuilder errbuf) {  


            if (packet.hasHeader(ip)){
                sourceIpRaw = ip.source();
                destinationIpRaw = ip.destination();

                sourceIp = org.jnetpcap.packet.format.FormatUtils.ip(sourceIpRaw);  
                destinationIp = org.jnetpcap.packet.format.FormatUtils.ip(destinationIpRaw);  
            }

            if (packet.hasHeader(tcp)){
                protocol = tcp.getName();
                length = tcp.size();

                int payloadOffset = tcp.getOffset() + tcp.size();  
                int payloadLength = tcp.getPayloadLength();  

                buffer.peer(packet, payloadOffset, payloadLength); // No copies, by native reference  
                info = buffer.toHexdump();
            } else if (packet.hasHeader(udp)){
                protocol = udp.getName();
                length = udp.size();


                int payloadOffset = udp.getOffset() + udp.size();  
                int payloadLength = udp.getPayloadLength();  

                buffer.peer(packet, payloadOffset, payloadLength); // No copies, by native reference  
                info = buffer.toHexdump();
            }

            if (packet.hasHeader(payload)){

                infoRaw = payload.getPayload();
                length = payload.size();

            }


            frameData.add(new Frame(packet.getCaptureHeader().timestampInMillis(), sourceIp, destinationIp, protocol, length, info ));
            //System.out.print(i+"\n");
            //i=i+1;
        }  

    };
    pcap.loop(numFrames, packetHandler , errbuf);  
    pcap.close();


    return frameData;
}

这段代码对于前 400k 个包来说速度非常快,但之后就慢了很多。前 400k 个包裹大约需要 1 分钟,其余大约需要 10 分钟。这里的问题是什么?

这不是列表变得太耗时了,不是吗?列表方法添加是 O(1),不是吗?

我也在官方 jnetpcap 论坛上问过这个问题,但它不是很活跃。

编辑:

事实证明,由于堆的使用,它的速度大大降低了。有什么办法可以减少这种情况吗?

正如探查器向您展示的那样,您 运行 内存不足并且开始变慢。

要么使用 -Xmx 提供更多内存,要么不要一次将所有数据包加载到内存中。