google / gopacket

Provides packet processing capabilities for Go
BSD 3-Clause "New" or "Revised" License
6.33k stars 1.13k forks source link

Extremely big memory cunsumption in PF_RING mode #17

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Hello!

For this simple code http://play.golang.org/p/E2CakSJ-7s I found unexpectedly 
big memory consumption and possible memory leak.

/usr/bin/time --verbose ./anomaly_detector
unexpected fault address 0x7f1f3e3ea828
throw: fault
[signal 0xb code=0x1 addr=0x7f1f3e3ea828 pc=0x7f1efd3963e0]

goroutine 1 [chan receive]:
main.main()
    /root/traffic_anomaly_detector/anomaly_detector.go:23 +0x1ce

goroutine 2 [syscall]:
created by runtime.main
    /home/michael/DPKG/golang/src/pkg/runtime/proc.c:221

goroutine 3 [syscall]:
code.google.com/p/gopacket/pfring._Cfunc_pfring_recv(0x4b0c2e0, 0xf84053d1d0)
    /tmp/go-build365217384/code.google.com/p/gopacket/pfring/_obj/_cgo_defun.c:105 +0x2f
code.google.com/p/gopacket/pfring.(*Ring).ReadPacketDataTo(0xf84053d0f0, 
0xf8422c9e80, 0x8000000080, 0x0, 0x0, ...)
    /tmp/go-build365217384/code.google.com/p/gopacket/pfring/_obj/_cgo_gotypes.go:927 +0xae
code.google.com/p/gopacket/pfring.(*Ring).ReadPacketData(0xf84053d0f0, 
0xf8422c9e80, 0x8000000080, 0x0, 0x0, ...)
    /tmp/go-build365217384/code.google.com/p/gopacket/pfring/_obj/_cgo_gotypes.go:945 +0xca
code.google.com/p/gopacket.(*PacketSource).NextPacket(0xf8417ff4b0, 
0xf841803000, 0xf840152f00, 0xf8422cc900)
    /usr/lib/go/src/pkg/code.google.com/p/gopacket/packet.go:658 +0x57
code.google.com/p/gopacket.(*PacketSource).packetsToChannel(0xf8417ff4b0, 
0xf841803000, 0x0, 0x0)
    /usr/lib/go/src/pkg/code.google.com/p/gopacket/packet.go:675 +0x45
created by code.google.com/p/gopacket.(*PacketSource).Packets
    /usr/lib/go/src/pkg/code.google.com/p/gopacket/packet.go:695 +0x54
Command exited with non-zero status 2
    Command being timed: "./anomaly_detector"
    User time (seconds): 0.55
    System time (seconds): 0.08
    Percent of CPU this job got: 83%
    Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.77
    Average shared text size (kbytes): 0
    Average unshared data size (kbytes): 0
    Average stack size (kbytes): 0
    Average total size (kbytes): 0
    Maximum resident set size (kbytes): 46196
    Average resident set size (kbytes): 0
    Major (requiring I/O) page faults: 0
    Minor (reclaiming a frame) page faults: 13666
    Voluntary context switches: 25921
    Involuntary context switches: 163
    Swaps: 0
    File system inputs: 0
    File system outputs: 0
    Socket messages sent: 0
    Socket messages received: 0
    Signals delivered: 0
    Page size (bytes): 4096
    Exit status: 2

Original issue reported on code.google.com by pavel.odintsov on 23 Jun 2014 at 8:50

GoogleCodeExporter commented 9 years ago
I think this may just be the fact that the GC is taking a while to run.  Could 
you try the following:

http://play.golang.org/p/a3SEI3UInn

If that shows a lot of memory before the GC and little memory after, then it's 
not a memory leak, just a bad use of the GC.

If you look at 
https://code.google.com/p/gopacket/source/browse/pfring/pfring.go#134, you'll 
notice that whenever we issue a call to PFRing, we alloc a buffer of size 
snaplen.  Most of that isn't used, hence there's a good chance we over-use 
memory, especially with high snaplens.  We could optimize this a bit (create a 
buffer that's N*snaplen, and just return pieces of it), but that could lead to 
other problems (keeping one packet around means big buffer stuck in memory and 
un-GC-able).

You can avoid memory issues using pfring's ReadPacketDataTo or 
ZeroCopyReadPacketData functions to not allocate a buffer every time a packet 
is read in.  That means passing the data into gopacket.NewPacket yourself, but 
the upsides are pretty big :)
Read the docs on ZeroCopyPacketData carefully if you decide to go that route, 
it can be finicky ;)

Original comment by gconnell@google.com on 23 Jun 2014 at 9:01

GoogleCodeExporter commented 9 years ago
I'm going to mark as WontFix right now, but feel free to push back if you find 
this is actually a memory leak, or if you think there's other things we could 
do to make this better.

Original comment by gconnell@google.com on 25 Jun 2014 at 9:37