Search code examples
javaperformancejnetpcap

JnetPcap: reading from offline file very slow


I'm building a sort of custom version of wireshark with jnetpcap v1.4r1425. I just want to open offline pcap files and display them in my tableview, which works great except for the speed. The files I open are around 100mb with 700k packages.

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;
}

This code is very fast for the first maybe 400k packages, but after that it slows down a lot. It needs around 1 minute for the first 400k packages and around 10 minutes for the rest. What is the issue here?

It's not that the list is getting too timeconsuming to work with is it? the listmethod add is O(1), isnt it?

I asked about this on the official jnetpcap forums too but it's not very active.

edit:

enter image description here

turn out it slows down massively because of the heap usage. Is there a way to reduce this?


Solution

  • As the profiler showed you, you're running low on memory and it starts to slow down.

    Either give more memory with -Xmx or don't load all the packets into memory at once.