jNetPcap does everything possible to avoid have to copy the packet data. So when your packet handler receives a buffer or a packet object from jNetPcap library you know that no data copies were done by jNetPcap itself. The data is passed into java by reference only.
If the underlying platform's kernel supports no packet copies, then that packet potentially arrives to your java handler/callback directly out of the memory location where the physical network interface placed it. Unfortunately this type of information is currently programatically inaccessible.
However if the application is capable of processing the packet immediately, then that packet can be discarded without having to make any copies. This is not always the case and sometimes the packet needs to be copied out of libpcap controlled buffer into more permanent user controlled space. This can be done very efficiently using low level native platforms copy functions. You just use any existing
JNetPcap.transferTo() methods. The library also provides a custom
JMemoryPool designed to allocate and space for this purpose alone, copying packet and state data as efficiently as possible.
Even the packet and buffer java objects, are reused where possible. The same buffer and packet instance is reused by peering to new memory location when a new packet is received. The user gets a fully functioning packet or buffer object, the same one he may have received before, that is now pointing at the next packet. The implemented literally reuses the exact same packet, not a cache of packets. Every set of the dispatch loop with calls
Pcap.dispatch() allocates a new java buffer or packet object to be used by that loop. To dispatch to the user using that java object.
Therefore the decision to reallocate memory, do deep copies and so forth is completely left up to the user to do at the appropriate time. Since libpcap and the scanner can supply more than one packet's buffer full, the user can also choose to peer a new buffer or packet object without doing any deep copies. That is a new java object would be allocated and would take over the references from the dispatch buffer or packet object. This way only a single java object needs to be created to peer with the packet buffer without data copies. This allows a packet or buffer to persist longer than a single interation of the dispatch loop, although since we do not know exactly when libpcap buffer is wrapped around and when any of our references we are holding to that buffers internal memory become unusable, it is typically safer to always reallocate and copy data into a new buffer. None the less it is possible to calculate the amount of time or number of packets that can fit into a libpcap and scanner buffers and possible tune packet queues to match or come in under those numbers allowing packets to be queued while still leaving the packet data in original buffers.